I've seen many JQuery examples that make use of $.each to loop through a JSON array. However, what need to do is individually grab items 0 - 3 and pass them to another function called "Search". Here's what I've come up with.
$.getJSON("http://localhost:61741/binggame/play?cat=Body%20Parts", {
tags: "English",
tagmode: "any",
format: "json"
},
function (data) {
Search(data.items[0], "Box1_Image");
Search(data.items[1], "Box2_Image");
Search(data.items[2], "Box3_Image");
Search(data.items[3], "Box4_Image");
});
I'm fairly certain that data.items[] is not the correct syntax.
Here's a sample of my JSON:
{"nouns":[
{
"ID":26,
"Category":"Body Parts",
"English":"muscle",
"Pinyin":"gei yUk",
"Image1":null,
"Audio1":null
},
{
"ID":27,
"Category":"Body Parts",
"English":"neck",
"Pinyin":"gen",
"Image1":null,
"Audio1":null
},
{
"ID":28,
"Category":"Body Parts",
"English":"nose",
"Pinyin":"bei",
"Image1":null,
"Audio1":null
},
{
"ID":29,
"Category":"Body Parts",
"English":"rib",
"Pinyin":"lat gwt",
"Image1":null,
"Audio1":null
}
]}
For this sample, the value of data.items[0] should be "muscle", data.items[1] should be "neck", data.items[2] should be "nose" and data.items[3] should be "rib".
Can someone point out to me what I've done wrong?
Can someone point out to me what I've done wrong?
To start, there is no property names items in your JSON.
If you want to get "muscle": data.nouns[0].English
If you want to get "neck": data.nouns[1].English
and so on:
function (data) {
Search(data.nouns[0].English, "Box1_Image");
Search(data.nouns[1].English, "Box2_Image");
Search(data.nouns[2].English, "Box3_Image");
Search(data.nouns[3].English, "Box4_Image");
});
or, to stay DRYer:
function (data) {
var nouns = data.nouns;
function getNoun(i) {
return nouns[i].English;
}
Search(getNoun(0), "Box1_Image");
Search(getNoun(1), "Box2_Image");
Search(getNoun(2), "Box3_Image");
Search(getNoun(3), "Box4_Image");
});
or better still:
function (data) {
var nouns = data.nouns;
for (var i=0; i<4; i++) {
Search(nouns[i].English, 'Box' + (i+1) + '_Image');
}
});
I assume you are manipulating the list in the nouns property and in that case it would be:
for (var i = 0, l = data.nouns.length; i < l; i++) {
Search(data.nouns[i].English, 'Box' + (i + 1) + '_Image');
}
Related
I am trying to compare two array of object values based on the specific key. Two object has same keys based on that i have to check whether the values are equal or not. One array is actual JSON object and the second one is test data, we have to verify the test data with JSON object and moreover if the test data value is same, it might have some extra space we need to trim that value as well.
var actualObject= [
{
"q1": "componentWillMount"
},
{
"q2": "willComponentUpdate"
},
{
"q3": "setState"
},
{
"q4": "componentUpdated"
}
]
Var testData =[
{q1: "componentWillMount"},
{q2: "willComponentUpdate"},
{q3: " PropTypes"},
{q4: "componentDidMount"}]
I will get the testData values from the Html code, on selection of radio buttons. Now i need to check how many answer are correct with actual JSON.
JS Code for it:
var marks= 0;
var wrong = 0;
for(var k =0 ; k<actualObject.length;k++){
if(JSON.stringify(actualObject[k]) == JSON.stringify(testData[k])){
marks++;
}
else {
wrong++;
}
}
var actualObject = [{
"q1": "componentWillMount"
},
{
"q2": "willComponentUpdate"
},
{
"q3": "setState"
},
{
"q4": "componentUpdated"
}
]
var testData = [{
q1: "componentWillMount"
},
{
q2: "willComponentUpdate"
},
{
q3: " PropTypes"
},
{
q4: "componentDidMount"
}
];
var marks = 0;
var wrong = 0;
for (var k = 0; k < actualObject.length; k++) {
if (JSON.stringify(actualObject[k]) == JSON.stringify(testData[k])) {
marks++;
} else {
wrong++;
}
}
console.log(marks, wrong);
Actually i would like to take value from each key and compare it with the actualObject.
If I understand correctly something like this should work:
Object.entries(testData).forEach(function (entry) {
if (actualObject[entry[0]] === entry[1].trim()) {
//answers match
} else {
//answers don't match
}
});
If you need to compare regardless of case then change entry[1].trim() to entry[1].trim().toLowerCase().
EDIT:
Just to remind you that maybe you should add a check whether or not the values in the test data are null/undefined, if they are strings or not, etc.
Okay so I'm using angular to get a json saved to my computer to recreate a github gradebook.
I can get the data with my $http request but for the love of me all I want is to get a count of the number of issues with the label "Not Yet".
Here is the javascript:
$http.get('/api/github/repos/issues/all_issues/00All.json')
.then(function(response) {
console.log(response.data[0]);
var counter = 0;
for(var index = 0; index < response.data.length; index++) {
if(response.data[index].labels[0].name == "Not Yet") {
counter++;
};
};
console.log(counter);
});
That's the latest try, I also tried using lodash to get it earlier:
$http.get('/api/github/repos/issues/all_issues/00All.json')
.then(function(response) {
console.log(response);
mile.notYet.width = _.forEach(response.data, function(n){
var counter = 0;
if(_.result(_.find(n.labels[0], 'name')) == "Not Yet") {
counter++;
}
console.log(counter);
counter = ((counter/10) * 100) + '%';
});
});
This is a bit of the json data:
[
{
"url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11",
"labels_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/labels{/name}",
"comments_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/comments",
"events_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/events",
"html_url": "https://github.com/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11",
"id": 73013825,
"number": 11,
"title": "00 -- Brace Yourself -- BEN GRIFFITH",
"user": {
"login": "Epicurean306",
"id": 11682684,
"avatar_url": "https://avatars.githubusercontent.com/u/11682684?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/Epicurean306",
"html_url": "https://github.com/Epicurean306",
"followers_url": "https://api.github.com/users/Epicurean306/followers",
"following_url": "https://api.github.com/users/Epicurean306/following{/other_user}",
"gists_url": "https://api.github.com/users/Epicurean306/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Epicurean306/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Epicurean306/subscriptions",
"organizations_url": "https://api.github.com/users/Epicurean306/orgs",
"repos_url": "https://api.github.com/users/Epicurean306/repos",
"events_url": "https://api.github.com/users/Epicurean306/events{/privacy}",
"received_events_url": "https://api.github.com/users/Epicurean306/received_events",
"type": "User",
"site_admin": false
},
"labels": [
{
"url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/labels/Not%20Yet",
"name": "Not Yet",
"color": "e11d21"
}
],
As you can see the labels property is an object, nested in an array, nested in an object, nested in an array, real lovely. Putting labels[0] results in an error for me each time and doesn't get me a count. Can anybody tell me where I'm messing up please? Thank you!
If you need a solution that includes lodash, which is much more performant than the native high order functions then you can try this solution below:
var size = _(response.data)
.pluck('labels')
.flatten()
.where({ name: 'Not Yet' })
.size();
UPDATE:
If you want it to be more reusable, you can save a reference for a cloned chained sequence and simply supply another array for that cloned sequence.
var data1 = [/*array from data1*/];
var data2 = [/*array from data2*/];
var notYetSequence = _(data1)
.pluck('labels')
.flatten()
.where({ name: 'Not Yet' });
notYetSequence.size(); // returns data 1 count
notYetSequence.plant(data2).size(); // returns data 2 count
You don't need lodash for the task
var cnt = response.data
.map(function(i) { return i.labels; })
// here we extract labels object only (and get an array of arrays of objects)
.map(function(i) { return i.filter(function(l) { return l.name == 'Not yet'; }).length; })
// then for every nested array we return a number of items with
// Not Yet names (and get an array of numbers)
.filter(function(c) { return c > 0; })
// then we filter issues that don't have one (and still get an array of numbers)
.length;
// and finally get length (which is a number)
As a comparison, a plain for loop looks like:
var data = response.data;
var count = 0;
var re = /not yet/i;
for (var a, i=0, iLen=data.length; i<iLen; i++) {
a = data[i].labels;
for (var j=0, jLen=a.length; j<jLen; j++) {
if (re.test(a[j].name)) ++count;
}
}
So really not a lot of code either way, the for loop will be compatible with every browser ever (though using xmlHTTPRequest means at least ed 3+) and fastest… untested of course. ;-)
Hello i want to filter json data like sql query without the help of plugins like alasql.js or linq.js or any plugins.
for example
{
"Managing PCL": [
{
"idItScreen": "1436",
"topicName": "Managing PCL",
"isFav": 0,
"cdeItScreen": "ListActiveTarif",
"busScreenName": "My Current Tarif"
},
{
"idItScreen": "1437",
"topicName": "Managing PCL",
"isFav": 0,
"cdeItScreen": "ListTermineTarif",
"busScreenName": "History Tarif"
}
]
}
for example i need to get data where idItScreen>1430 so that json data must be displayed the main challenge is to do without plugins so please reccomend me a good solution to do this without plugins
First turn your JSON into a Javascript object:
var obj = JSON.parse(myJSON);
Then do your filtering:
var matches = [];
var arr = obj['Managing PCL'];
for (var i = 0; i < arr.length; i++) {
if (arr[i].idItScreen > 1430) {
matches.push(arr[i]);
}
}
Or using jQuery.grep:
var matches = jQuery.grep(obj['Managing PCL'], function(n, i) {
return n.idItScreen > 1430;
});
Now matches contains the matching items.
If you want to get the JSON again, just use JSON.stringify:
var filteredJSON = JSON.stringify({'Managing PCL': matches});
You can also simply use .filter:
var matches = [];
var all = obj['Managing PCL'];
var filtered = all.filter(function(){
return $(this).idItScreen > 1430;
})
You don't need to use jQuery for this. You can use the filter() method of Array.prototype. See the working snippet below:
var obj = {
"Managing PCL": [{
"idItScreen": "1436",
"topicName": "Managing PCL",
"isFav": 0,
"cdeItScreen": "ListActiveTarif",
"busScreenName": "My Current Tarif"
}, {
"idItScreen": "1437",
"topicName": "Managing PCL",
"isFav": 0,
"cdeItScreen": "ListTermineTarif",
"busScreenName": "History Tarif"
}]
};
var filteredArray = obj['Managing PCL'].filter(function(item) {
return item.idItScreen > 1430;
});
obj['Managing PCL'] = filteredArray;
document.getElementById('result').innerHTML = JSON.stringify(obj);
<div id="result"></div>
You don't need jQuery for this. Use filter on the data instead.
function filterData(data, key, value) {
return data.filter(function (el) {
return el[key] > value;
});
}
// Note, `filter` operates on arrays, so you need to specify the
// array that contains the data
var result = filterData(data['Managing PCL'], 'idItScreen', '1430');
Also note that filter returns a new array containing the objects that it's found that match your criteria. You can access those objects in the usual way: result[0], for example.
DEMO
You could even expand this to create a function that returns data based on the operator too, not just greater-than, by using a look-up object:
var lookup = {
'>': function (data, value) { return data > value; },
'<': function (data, value) { return data < value; },
'===': function (data, value) { return data === value; }
}
function filterData(data, key, operator, value) {
return data.filter(function (el) {
return lookup[operator](el[key], value);
});
}
filterData(data['Managing PCL'], 'idItScreen', '>', '1430');
filterData(data['Managing PCL'], 'idItScreen', '===', '1430');
DEMO
So i've been stuck trying to figure this out. I'm pretty sure I'm lacking a key piece of information. I'm grabbing some values from a JSON response. One contains a list of names. Another contains a list of URLs that correspond to the list of Names.
For instance:
{"names":"john,casey,davey",
"nameUrls":[{
"johnURL":"http://url.com",
"caseyURL":"http://url.com",
"daveyURL":"http://url.com"]}
names = (data.names).split(',');
$.each(data.nameUrls, function(key, val) {
for (var i = 0; i < names.length; i++) {
$("#left").append(val[names[i] + "URL"]);
}
})
Now the first one comes through just fine. But the rest come in undefined. So what am I doing wrong? Thanks in advance for your help.
Edit: Adding more code.
After fixing some syntax errors, here's the code which I tested in console and it's working.
var data = {
"names": "john,casey,davey",
"nameUrls": {
"johnURL": "http://url.com",
"caseyURL": "http://url.com",
"daveyURL": "http://url.com"
}
};
names = (data.names).split(',');
$.each(data.nameUrls, function (key, val) {
for (var i = 0; i < names.length; i++) {
$("#left").append(val[names[i] + "URL"]);
}
});
In above lines, I just fixed the syntax errors, however I believe this might not let you achieve what you want. Try the below code and let me know.
var data = {
"names": "john,casey,davey",
"nameUrls": {
"johnURL": "http://url1.com",
"caseyURL": "http://url2.com",
"daveyURL": "http://url3.com"
}
};
names = (data.names).split(',');
$.each(data.nameUrls, function (key, val) {
$("#left").append(val);
});
It seems to me like you should restructure your data so that there is an easier association amongst it.
Would something like this work for you?
data = [
{"name": "john", "url": "http://url.com"},
{"name": "casey", "url": "http://url.com"},
{"name": "davey", "url": "http://url.com"}
];
$.each(data, function(index, person) {
$('#left').append(person.url);
});
var data = {
"names": "john,casey,davey",
"nameUrls": {
"johnURL": "http://url.com",
"caseyURL": "http://url.com",
"daveyURL": "http://url.com"
}
};
$.each(data.names.split(','), function (i, v) {
$("#left").append( v + " ==> " + data.nameUrls[v + 'URL'] );
});
my data array
data : [
{
"name": "Autauga, AL",
"value": 5.6
},
{
"name": "Baldwin, AL",
"value": 5.3
},...
]
How can I retrieve the index of an array object if I just have the name "Autauga, AL"?
I am aware of the brute force loops. is there a better way?
In ECMAScript 5.1+, you can use the Array#filter method to get the actual object:
data.filter(function(item){return item.name == 'Autauga, AL'})[0]
That doesn't get you the index, though. You could do this:
data.map(function(item,index){
return [item, index]
}).filter(function(a){
return a[0].name == 'Autauga, AL'
})[0][1]
Those methods still wind up using loops under the covers, but I guess they look cooler..
For efficient access, you could build an index for the target field:
var dataIndexByName = {}, i, len;
for (i=0, len=data.length; i<len; ++i) {
dataIndexByName[data[i].name] = i
}
After which you can just look for dataIndexByName['Autauga, AL']. That also has the advantage of working in older implementations. It gets a bit more complicated if a given name might show up more than once in the original array, though.
You could do something like this:
for (var i = 0, len = data.length; i++) {
if (data[i].name.indexOf("Autauga, AL") > -1) {
return i;
}
}
You could write a small function to do the job based on Array.prototype.some:
function getIndex(arr, prop, value) {
var idx;
arr.some(function(v, i) {
if (v[prop] == value) {
idx = i;
return true;
}
});
return idx;
}
data = [{"name": "Autauga, AL","value": 5.6},
{"name": "Baldwin, AL","value": 5.3}];
console.log(getIndex(data, 'name', 'Baldwin, AL')); // 1
some is efficient because it stops when the callback first returns true. You may wisht to adjust the condition to suit.