How to get values by making a comparison in this JSON result - javascript

I have this JSON. I need to first compare values in teams with values in html_content.position[i] where i should be a loop var, and then if comparison returns true then get the value. See this example:
html_content.position[0][0].toLowerCase() = "navegantes";
Then I should compare with each value in teams and if there is any key that es equal then I should get the value, taking the example, I should get this value:
"img\/magallanes.jpg"
Can any give me some help here?

The problem is with this code you are using:
html_content.position[0][0].toLowerCase() = "navegantes";
html_content.position actually is an array of arrays of arrays (though in your example data each inner array is only of length 1... is that always true?), so you need one more bracket operator on there to test the value of html_content.position[i][0][0]
Here is an example that incorporates your JSON data, looks through each team, and finds the corresponding position: (see below for working JSfiddle demo)
The solution code:
var matches = [];
for(var teamName in json.teams)
{
for(var i = 0, len = json.html_content.position.length; i < len; i++)
{
if(json.html_content.position[i][0][0].toLowerCase() === teamName.toLowerCase())
{
// found a match. do something with it..
matches[matches.length] = {Name: teamName, Value: json.teams[teamName]};
break;
}
}
}
The JSON: (for reference since previously was only published on 3rd party site)
var json = {
"response":true,
"teams":{
"navegantes":"img\/magallanes.jpg",
"tigres":"img\/tigres.jpg",
"caribes":"img\/caribes.jpg",
"leones":"img\/leones.jpg",
"aguilas":"img\/aguilas.jpg",
"tiburones":"img\/tiburones.jpg",
"bravos":"img\/bravos.jpg",
"cardenales":"img\/cardenales.jpg",
"maga":"img\/magallanes.jpg",
"tigr":"img\/tigres.jpg",
"cari":"img\/caribes.jpg",
"leon":"img\/leones.jpg",
"agui":"img\/aguilas.jpg",
"tibu":"img\/tiburones.jpg",
"brav":"img\/bravos.jpg",
"card":"img\/cardenales.jpg"
},
"html_content":{
"position":[
[
[
"Navegantes",
"14",
"10",
"4",
"0"
]
],
[
[
"Tigres",
"14",
"10",
"4",
"0"
]
],
[
[
"Caribes",
"14",
"9",
"5",
"1"
]
],
[
[
"Leones",
"14",
"9",
"5",
"1"
]
],
[
[
"Tiburones",
"13",
"5",
"8",
"4.5"
]
],
[
[
"Aguilas",
"14",
"5",
"9",
"5"
]
],
[
[
"Bravos",
"14",
"4",
"10",
"6"
]
],
[
[
"Cardenales",
"13",
"3",
"10",
"6.5"
]
]
],
"current":[
[
"MAGA",
"CARI",
"7:00 pm",
"PUERTO LA CRUZ"
],
[
"AGUI",
"LEON",
"4:00 pm",
"CARACAS"
],
[
"BRAV",
"TIGR",
"5:30 pm",
"MARACAY"
],
[
"TIBU",
"CARD",
"5:30 pm",
"BARQUISIMETO"
]
],
"next":[
[
"MAGA",
"CARI",
"6:00 pm",
"PUERTO LA CRUZ"
],
[
"AGUI",
"LEON",
"1:00 pm",
"CARACAS"
],
[
"TIBU",
"TIGR",
"5:30 pm",
"MARACAY"
],
[
"BRAV",
"CARD",
"2:00 pm",
"BARQUISIMETO"
]
],
"previous":[
]
}
};
See an example fiddle here: http://jsfiddle.net/VqHpJ/
The example fiddle creates an array of matches which is a collection of objects representing the team Name and the Value for the associated image, and spits them out in a list. (Of course, you didn't say what you want to do once you found a match, so you can adapt this as needed).
This is a fairly typical pattern for matching elements in two arrays (one nested loop), and in my example it assumes that only one match should be found, in which case it will break out of the nested loop and start looking for the next team. Therefore the performance is O(n^2) in the worst case.
This is a little tricky (but not difficult) because the teams object does not really have an array of teams, it has specific properties for each team name. Therefore the solution was to iterate over the properties of the teams object using for(var teamName in json.teams). If you are the author of the function that generates the JSON, you may want to consider revising it to instead generate an array of teams, for example:
var json = {
"response":true,
"teams":
[
{ "Name": "navegantes", "ImageUrl": "img\/magallanes.jpg" },
{ "Name": "tigres", "ImageUrl": "img\/tigres.jpg"},
{ "Name": "caribes", "ImageUrl": "img\/caribes.jpg"},
...
]
...
}

Assuming you have a JSON string that you parsed into an object that looks like the following
var json = {"teams":{
"navegantes":"img\/magallanes.jpg",
"tigres":"img\/tigres.jpg",
"caribes":"img\/caribes.jpg",
"leones":"img\/leones.jpg",
"aguilas":"img\/aguilas.jpg",
...
}};
You can iterate using each()
$.each(json.teams, function(i, v){
console.log(i);
console.log(v);
});

Related

Is there a way to update items in an array with JsonPatch?

The API to be invoked uses JsonPatch. The following is a sample JSON.
{ "hello": false
, "array1":
[ { "subarray": [ "k2", "k1"] }
, { "subarray": [ "k1"] }
]
}
I would like to update both the subarrays (elements of the array1). There could be N number of elements/items in array1 that I'm not aware of when calling this API.
Now I can do the following if I am aware of the the size of array1.
[{ "op": "add", "path": "/array1/0/subarray/0", "value": "gk" }]
[{ "op": "add", "path": "/array1/1/subarray/0", "value": "gk" }]
But since I'm not aware of the the size of array1, it does not seem that this can be achieved using JsonPointer. Is there something that can be done to do an update that targets all the elements of array1 (i.e all the subarrays) in one go? Something like this:
[{ "op": "add", "path": "/array1/*/subarray1/0", "value": "gk-new" }]
After invocation, the resulting subarrays should have an additional element "gk-new" in addition to what they have?
There is no wildcard support in JsonPatch or JsonPointer. Therefore, what is asked in the question is not possible.

Find the length of JSON object for identical key values [duplicate]

This question already has answers here:
How to count duplicate value in an array in javascript
(35 answers)
Closed 5 years ago.
I have a JSON file. I want to find the length of the JSON object where one key-value pair is similar. Like,
https://api.myjson.com/bins/h5mgv
[
{
"receive_date": "2013-11-04",
"responses": "2",
"name": "west"
},
{
"receive_date": "2013-11-04",
"responses": "8668",
"name": "west"
},
{
"receive_date": "2013-11-13",
"responses": "121",
"name": "east"
}
]
In the above example, length is 2 where "name": "west" and length is 1 where "name": "east" . I want to iterate through the JSON and find the identical values for the key name using Javascript. Output should look like,
east : 1
west : 2
By using length() I can find the length of whole JSON but what is recommended way to find the length for identical key values.
You can use reduce to get a new object listing the count of each name:
const myArray = [
{
"receive_date": "2013-11-04",
"responses": "2",
"name": "west"
},
{
"receive_date": "2013-11-04",
"responses": "8668",
"name": "west"
},
{
"receive_date": "2013-11-13",
"responses": "121",
"name": "east"
}
]
const myCounts = myArray.reduce((counts, item) => {
if (counts[item.name] === undefined) counts[item.name] = 0;
counts[item.name]++;
return counts;
}, {});
console.log(myCounts);
This produces the result:
{
"west": 2,
"east": 1
}

Javascript collection find values with Lodash

I have an array shown as below. I want to know which values inside departure and arrival fields.
Array :
var data = {
"origin": "Antalya",
"destination": "IST",
"flights": [{
"provider": "thy",
"time": "2017-07-07 10:30",
"legs": [{
"departure": "AYT",
"arrival": "IST"
}]
},{
"provider": "thy",
"time": "2017-07-07 14:30",
"legs": [{
"departure": "AYT",
"arrival": "ESB"
},{
"departure": "ESB",
"arrival": "IST"
}]
},{
"provider": "pegasus",
"time": "2017-07-07 06:30",
"legs": [{
"departure": "AYT",
"arrival": "ADB"
},{
"departure": "ADB",
"arrival": "IST"
}]
}]
};
I want to new array like this :
["AYT","IST","ESB","ADB"]
How can i handle it using lodash?
Here's a solution using lodash:
let result = _(data.flights)
.flatMap('legs')
.flatMap(_.values)
.uniq()
.value();
First we get a flattened array of legs, transform that into a flattened array of the values of the properties of each leg, before finally getting the unique values.
Well loop through your data and create a string array, and then use the uniq function, like:
var data = {"origin":"Antalya","destination":"IST","flights":[{"provider":"thy","time":"2017-07-07 10:30","legs":[{"departure":"AYT","arrival":"IST"}]},{"provider":"thy","time":"2017-07-07 14:30","legs":[{"departure":"AYT","arrival":"ESB"},{"departure":"ESB","arrival":"IST"}]},{"provider":"pegasus","time":"2017-07-07 06:30","legs":[{"departure":"AYT","arrival":"ADB"},{"departure":"ADB","arrival":"IST"}]}]};
var legs = [];
_.each(data.flights, flight => {
_.each(flight.legs, leg => {
legs.push(leg.departure);
legs.push(leg.arrival);
});
});
console.log(_.uniq(legs));
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>

Javascript looping through elements and adding to table

I'm having trouble finding a solution that will help me loop through a bunch of elements and putting the chosen values into a table. I've been able to withdraw some values but the method isn't dynamic.
Here is an example:
var Table = {
"credit": {
"link": "site link",
"logoUrl": "logo url",
"message": "message"
},
"groups": [
{
"labels": [
{
"name": "Western Conference",
"type": "conference"
},
{
"name": "Central Division",
"type": "division"
}
],
"standings": [
{
"stats": [
{
"name": "gp",
"value": 20
},
{
"name": "w",
"value": 17
},
{
"name": "l",
"value": 0
},
{
"name": "gf",
"value": 64
},
{
"name": "ga",
"value": 37
},
{
"name": "gd",
"value": 27
},
{
"name": "pts",
"value": 37
}
],
"team": {
"id": 12345,
"link": "team link",
"name": "team name",
"shortName": "team"
}
},
This is the structure of the elements. So far I've used this:
document.getElementById("sGamesPlayed").innerHTML=Table.groups[0].standings[0].stats[0].value;
to withdraw values. However there are more teams, stats and divisions so I would need some kind of loop to go through the elements and put the into a dynamic table.
I would consider you to look at http://underscorejs.org/.
it provides a bunch of utility functions that could help you,
for example, _.each() helps you loop through JSON properties.
for the sample objects you've given (after completing the missing brackets at the end),
_.each(Table.groups[0].standings[0].stats, function(stats){
console.log(stats['name']+","+stats['value'])
})
gives me:
gp,20
w,17
l,0
gf,64
ga,37
gd,27
pts,37
how it works is that you provide the object you want as the first argument and the function that you give as the second argument will be called with each element of the first argument (Assuming it is a list).
I would also urge you to look at underscore templating that you can use to render your table where i put the console.log :
http://net.tutsplus.com/tutorials/javascript-ajax/getting-cozy-with-underscore-js/
http://scriptble.com/2011/01/28/underscore-js-templates/
I guess your question is about filtering the values of the array standings. In order to do that you can use the jQuery grep function (if you want to use jQuery).
For example you can write:
var arr = $.grep(Table.groups[0].standings[0].stats, function(d){return d.value>25})
Which will give
arr = [{"name": "gf","value": 64}, {"name": "ga", "value": 37},{"name": "gd", "value": 27},{"name": "pts", "value": 37}]
If this is not what you meant, can you please create a jsFiddle with a sample of what you want?
Depending on what you want to do with the results, you can go over the object using a scheme like:
var groups, standings, stats, value;
groups = Table.groups;
// Do stuff with groups
for (var i=0, iLen=groups.length; i<iLen; i++) {
standings = groups[i].standings;
// Do stuff with standings
for (var j=0, jLen=standings.length; j<jLen; j++) {
stats = standings[j];
// Do stuff with stats
for (var k=0, kLen=stats.length; k<kLen; k++) {
value = stats[k].value;
// Do stuff with value
}
}
}
Of course I have no idea what the data is for, what the overall structure is or how you want to present it. But if you have deeply nested data, all you can do is dig into it. You might be able to write a recursive function, but it might also become very difficult to maintain if the data structure is complex.

Is it possible to store integers as keys in a javascript object?

I'm creating an index file in JSON, which I'm using as a sort-of-database index for a javascript application I'm working on.
My index will look like this:
{
"_id": "acomplex_indices.json",
"indexAB": {
"title": {
"Shawshank Redemption": [
"0"
],
"Godfather": [
"1"
],
"Godfather 2": [
"2"
],
"Pulp Fiction": [
"3"
],
"The Good, The Bad and The Ugly": [
"4"
],
"12 Angry Men": [
"5"
],
"The Dark Knight": [
"6"
],
"Schindlers List": [
"7"
],
"Lord of the Rings - Return of the King": [
"8"
],
"Fight Club": [
"9"
],
"Star Wars Episode V": [
"10"
],
"Lord Of the Rings - Fellowship of the Ring": [
"11"
],
"One flew over the Cuckoo's Nest": [
"12"
],
"Inception": [
"13"
],
"Godfellas": [
"14"
]
},
"year": {
"1994": [
"0",
"3"
],
"1972": [
"1"
],
"1974": [
"2"
],
"1966": [
"4"
],
"1957": [
"5"
],
"2008": [
"6"
],
"1993": [
"7"
],
"2003": [
"8"
],
"1999": [
"9"
],
"1980": [
"10"
],
"2001": [
"11"
],
"1975": [
"12"
],
"2010": [
"13"
],
"1990": [
"14"
]
}
}
}
So for every keyword (like Pulp Fiction), I'm storing the matching document-id(s).
My problem is with integers/numbers/non-string data, like the release year in the above example. This is stored as a string, while I had hoped it would be stored as a number.
I'm creating the index entries like this:
// indices = the current index file
// doc = the document to update the index with
// priv.indices = all indices defined for this application instance
// priv.indices.fields = index fields e.g. "year", "director", "title"
// priv.indices.name = name of this index
priv.updateIndices = function (indices, doc) {
var i, j, index, value, label, key, l = priv.indices.length;
// loop all indices to add document
for (i = 0; i < l; i += 1) {
index = {};
index.reference = priv.indices[i];
index.reference_size = index.reference.fields.length;
index.current = indices[index.reference.name];
for (j = 0; j < index.reference_size; j += 1) {
label = index.reference.fields[j]; // like "year"
value = doc[label]; // like 1985
// if document has a label field (e.g. doc.year = 1985)
if (value !== undefined) {
// check if the index file already contains an entry for 1985
index.current_size = priv.getObjectSize(index.current[label]);
if (index.current_size > 0) {
// check if the document id is already in the index
// in case the data is updated (e.g. change 1982 to 1985)
key = priv.searchIndexByValue(
index.current[label],
doc._id,
"key"
);
if (!!key) {
delete index.current[label][key];
}
}
// create a new array if 1985 is not in the index yet
if (index.current[label][value] === undefined) {
index.current[label][value] = [];
}
// add the document id to an existing entry
index.current[label][value].push(doc._id);
}
}
}
return indices;
};
This works fine, except that fields I want to store as non-strings (integers, numbers or datetime), like the year in the above example end up as strings in my index.
Question:
Is it at all possible to store "non-string" types in a JSON document? If so, can I also store the key of a key/value pair as a "non-string" element.
If not, would I have to add a parameter to my index definitions declaring the type of each key in order to modify the key-string when I run into it or is there a better way to do it?
Thanks!
Is it at all possible to store "non-string" types in a JSON document?
Yes. The value of a property can be a string, number, boolean, object, array or null (undefined is a notable exception - it's a native JavaScript type but it's not a valid JSON value).
Can I also store the key of a key/value pair as a "non-string" element?
No. The key name must always be a string. However, that doesn't mean you can't parse that string into some other JavaScript type. For example, if you have a string but need a number, you can use the parseInt function, or the unary + operator.
See the JSON grammar for more detail.
no you can't, in JSON keys are strings.
the best you can do is storing string representations of those keys, wether integer or objects(more complicated, you have to build a serialization function).
If you want to use only consecutive integers keys starting from 0, then you can use arrays.
According to the json spec, you can have a number anywhere you could have a value. So the key of an object must be a string, but the value can be a number. Also any of the values in an array can be a number.
The spec is beside the point though; I believe the issue is this line:
index.current[label][value].push(doc._id);
When you read doc._id, that is a string. If you want to store it in the JSON as a number, you need to cast it:
index.current[label][value].push(parseInt(doc._id, 10));
Also note that having just numbers as IDs is not valid HTML.

Categories

Resources