I am trying to sort sets of associated key value pairs. They look like this:
{"word":"a","votes":9326,"userMade":"FALSE","limiter":"FALSE"},
But organized into labeled subsets of preferably a string or perhaps an index if necessary.
The data-set is a vote-per-use table of most used english words being parsed into pages.
I will be appending them as text to other html elements due to the constraints my use case, makes it a bit tricky, however, for an example I could work with a simple console.log of the page value followed by the console.log of every word value stored within that page. I need the order preserved. so probably indexed. I will also need to be able to sort each page by the votes value, but I think I can figure the rest out for that.
I have found tutorials on how to search through key-value pairs, but I cannot find how to do all of the following with one solution:
A: access the value of word
B: maintain the order of the data-set, allowing me to append them to the matching html element
C: allows me the opportunity to change which set of elements I am appending to when i have finished looping through a single member of the parent index (the one recording the page)
I imagine it is some combination of for/of and for/in, but I'm getting a headache. Please help?
addl info:
function would run at app startup or when the dataset being examined is changed.
function would take a large dataset filled with around 200 page number values, each with 60+ sets of data like the one listed above, the contents of a single page index for example:
{"word":"a","votes":9326,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aaron","votes":4129,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abandoned","votes":1289,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abc","votes":5449,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aberdeen","votes":641,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abilities","votes":2210,"userMade":"FALSE","limiter":"FALSE"},
{"word":"ability","votes":7838,"userMade":"FALSE","limiter":"FALSE"},
{"word":"able","votes":8649,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aboriginal","votes":1837,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abortion","votes":3232,"userMade":"FALSE","limiter":"FALSE"},
{"word":"about","votes":9295,"userMade":"FALSE","limiter":"FALSE"},
{"word":"above","votes":8818,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abraham","votes":867,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abroad","votes":4969,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abs","votes":2415,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absence","votes":4934,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absent","votes":2937,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absolute","votes":5251,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absolutely","votes":5936,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absorption","votes":285,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abstract","votes":7946,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abstracts","votes":1907,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abuse","votes":7238,"userMade":"FALSE","limiter":"FALSE"},
{"word":"academic","votes":7917,"userMade":"FALSE","limiter":"FALSE"},
{"word":"academics","votes":1706,"userMade":"FALSE","limiter":"FALSE"},
{"word":"academy","votes":6755,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acc","votes":6469,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accent","votes":1020,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accept","votes":7547,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acceptable","votes":4907,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acceptance","votes":7273,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accepted","votes":7684,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accepting","votes":1789,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accepts","votes":1535,"userMade":"FALSE","limiter":"FALSE"},
{"word":"access","votes":9031,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessed","votes":2932,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessibility","votes":5702,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessible","votes":5662,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessing","votes":2096,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessories","votes":8875,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessory","votes":5661,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accident","votes":5664,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accidents","votes":2991,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accommodate","votes":1807,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accommodation","votes":8059,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accommodations","votes":3885,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accompanied","votes":2532,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accompanying","votes":664,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accomplish","votes":1070,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accomplished","votes":2419,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accordance","votes":6434,"userMade":"FALSE","limiter":"FALSE"},
{"word":"according","votes":8282,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accordingly","votes":3003,"userMade":"FALSE","limiter":"FALSE"},
{"word":"account","votes":8996,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accountability","votes":3029,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accounting","votes":7459,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accounts","votes":7507,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accreditation","votes":1605,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accredited","votes":3027,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accuracy","votes":6779,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accurate","votes":6427,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accurately","votes":1493,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accused","votes":2853,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acdbentity","votes":1389,"userMade":"FALSE","limiter":"FALSE"},
and the output would ultimately append the value paired with each word to a specific button through iteration, but also sorted by the page value.
each page is a set of buttons in a 3d object that looks like this:
the text is appended to each button which in turn is a 3d object embeded in an html object using aframe. I can make the appending code.
You can use Object.entries() to get the key value pairs of an object.
var words = [
{"word":"a","votes":9326,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aaron","votes":4129,"userMade":"FALSE","limiter":"FALSE"}
];
words.forEach((wordEntry) => {
var keyValuePairs = Object.entries(wordEntry);
keyValuePairs.forEach((kv) => {
console.log(`key: ${kv[0]} value: ${kv[1]}`);
});
});
my latest attempt looks like this:
for (let p=1; p<129; p++){
for (let b=1; b<68; b++){
let pTpl = (p).toLocaleString(undefined, {minimumIntegerDigits: 3});
let bDbl = (b).toLocaleString(undefined, {minimumIntegerDigits: 2});
var `#fCont${pTpl}${bDbl}` = document.createElement('a-text');
`fCont${pTpl}${bDbl}`.setAttribute('value', 'engWordLib[p,b,0]');
`fCont${pTpl}${bDbl}`.setAttribute('votes', 'engWordLib[p,b,1]');
`fCont${pTpl}${bDbl}`.setAttribute('userMade', 'engWordLib[p,b,2]');
`fCont${pTpl}${bDbl}`.setAttribute('limiter', 'engWordLib[p,b,3]');
`fCont${pTpl}${bDbl}`.setAttribute('visible', 'false');
`fBtn${bDbl}`.appendChild(`#fCont${pTpl}${bDbl}`)
}
}
please note that I havent checked this for errors. I still think this code is to WET and I would prefer the key names for the properties be preserved in the datastructure rather than tacked on when it's appended to the page. I guess I could add a dimension to the array.... seems kind of messy when an object property value has the key value pairs right in it. cant get the iteration of objects in an array down though.... Will continue to persue a cleaner method.
I'm trying to figure out on how to access data in JSON format and have gone a whole day searching for ways but I still can't find a solution to fit my needs. The closest relative question to my problem is this question but to no avail.
Basically I am retrieving data from $.ajax() which returns in JSON format.
[{"v":"233","pv":"1.83","avd":"00:01:58","nv":"82.83%","br":"75.11%"},
{"v":"17","pv":"3.65","avd":"00:08:31","nv":"70.59%","br":"58.82%"},
{"v":"9","pv":"2.22","avd":"00:01:51","nv":"0.00%","br":"44.44%"}]
[{"date":"2013-02-01","visits":63},
{"date":"2013-02-02","visits":30}]
My problem is how can I access the elements inside the JSON, say I want to get all values of "nv" or all values of "date" on the second bracket, in javascript? I Am new at things like these so am not familiar with the terminologies, sorry for that.
Below is my code:
var Data = $.ajax({
url: url,
type: 'POST',
dataType:"json",
async: false
}).responseText;
console.log(Data);
url is a variable that is passed inside my function in case you might ask.
Update: See Anthony Grist's comment on your question, I missed the fact that your JSON is invalid. Since he hasn't posted an answer, I'll pick it up.
Your JSON is invalid because you're returning two separate arrays, this one:
[{"v":"233","pv":"1.83","avd":"00:01:58","nv":"82.83%","br":"75.11%"},
{"v":"17","pv":"3.65","avd":"00:08:31","nv":"70.59%","br":"58.82%"},
{"v":"9","pv":"2.22","avd":"00:01:51","nv":"0.00%","br":"44.44%"}]
and this one:
[{"date":"2013-02-01","visits":63},
{"date":"2013-02-02","visits":30}]
You can't do that, because the top level of a JSON document must be one thing (an object or an array).
You could return an object with properties for each array:
{
"vdata":
[{"v":"233","pv":"1.83","avd":"00:01:58","nv":"82.83%","br":"75.11%"},
{"v":"17","pv":"3.65","avd":"00:08:31","nv":"70.59%","br":"58.82%"},
{"v":"9","pv":"2.22","avd":"00:01:51","nv":"0.00%","br":"44.44%"}
],
"datedata":
[{"date":"2013-02-01","visits":63},
{"date":"2013-02-02","visits":30}
]
}
After parsing (see below), you can access that data like this:
console.log(data.vdata[0].v); // "233"
console.log(data.datedata[0].date); // "2013-02-01"
Or an array with two slots, with each slot having one of your arrays in it:
[
[{"v":"233","pv":"1.83","avd":"00:01:58","nv":"82.83%","br":"75.11%"},
{"v":"17","pv":"3.65","avd":"00:08:31","nv":"70.59%","br":"58.82%"},
{"v":"9","pv":"2.22","avd":"00:01:51","nv":"0.00%","br":"44.44%"}
],
[{"date":"2013-02-01","visits":63},
{"date":"2013-02-02","visits":30}
]
]
After parsing (see below), you can access that data like this:
console.log(data[0][0].v); // "233"
console.log(data[1][0].date); // "2013-02-01"
Personally, I prefer using an object, since then it's clear which array I'm accessing.
Original answer:
jQuery will parse the JSON into an object for you and pass that to the success function, which you can then access just like any other object. In your case, the top level is an array. So:
$.ajax({
url: url,
type: 'POST',
dataType:"json",
async: false,
success: function(data) {
// Use the line from above that suits the way
// you updated your JSON structure
}
});
Side note: async: false is deprecated and will be removed at some point. It's generally not a good idea to do synchronous ajax requests, it tends to lock up the UI of the browser during the request. Instead, just structure your code to continue processing when the success callback is triggered.
If I understand your problem you need to access the same key for all objects in this array.
There is no direct method to do that, you have to iterate through all objects in this array and then find the desired key in each of those objects.
JSON.parse() will convert this string into a Javascript Object (JSON)
var myData = JSON.parse(Data);
for(var i = 0; i < myData.length; i++) {
console.log("This is the nv value of the " + i + " object: " + myData[i].nv);
}
On return of a JSON file I can't seem to be able to detect how many results are returned. The problem seems to be with the JSON file returning a diffrent number of items each time. At times it will return 1 item, then at other it will return more than 1. You see, I'm trying to get the very first result from the JSON file so I can display it. Now, If change the code everytime I know the number that will be returned, the following two bits of code work.. Artists.id; and Artists.id[0];, but I can't seem to make them work together, at the momment..
If 1 result is returned, Artists.id; will successfully bring back the artist ID;
If more than 1 result is returned Artists.id; will return "undefined".
So I need to change it to Artists.id[0]; if the JSON file returns more than 1 item. However when I change it to this, if the JSON conatins 1 item, it will return "undefined".
It seems I need some code to tell me if the returned array has 1 or more items. I've tried arr.length but that doesn't seem to be working (perhaps i miss-coded it). I also tried if(arr===undefined) and that failed to work too. The code below is what I have come up with, using the artistzero, but it is not working. Anyone has any advice? or a reason why the code below would not work?
Current Code:
$.ajax(
{
type: "GET",
url: id_url,
dataType: "jsonp",
success: function (responseData, textStatus, XMLHttpRequest)
{
if (responseData.Artists.Artist)
{
var Artists = responseData.Artists.Artist;
var artistzero = Artists.length;
if (artistzero >= 2)
{
// if more than one result is returned
var artisttype = Artists.id[0];
}
if (artistzero <= 1)
{
// if one result is returned
var artisttype = Artists.id;
}
}
else
{
$('body').append('No results');
}
}
});
Sample JSON with 1 result:
{"Artists":{"total":"1","count":"1","start":"1","errorCount":"0","Artist":{"id":"33291476","flags":"123010","catzillaID":"0","website":"","name":"Jamie T","rating":"-1","ItemInfo":{"Relevancy":{"index":"1316"}},"hotzillaID":"1809709440","url":"http://web.com/jamie-t/","trackCount":"96"}}}
Sample JSON with more than one result:
{"Artists":{"total":"1087","count":"3","start":"1","errorCount":"0","Artist":[{"id":"256212","flags":"123523","catzillaID":"1927205428","website":"http://www.bobmarley.com/","name":"Bob Marley","rating":"-1","ItemInfo":{"Relevancy":{"index":"718"}},"hotzillaID":"1802045595","url":"http://web.com/bob-marley/","trackCount":"12706"},{"id":"312874","flags":"124611","catzillaID":"1927580000","website":"http://www.bobdylan.com/","name":"Bob Dylan","rating":"-1","ItemInfo":{"Relevancy":{"index":"694"}},"hotzillaID":"1800021697","url":"http://web.com/bob-dylan/","trackCount":"4987"},{"id":"268472","flags":"41603","catzillaID":"1927193413","website":"","name":"Bob Wills","rating":"-1","ItemInfo":{"Relevancy":{"index":"644"}},"hotzillaID":"1800264434","url":"http://web.com/bob-wills/","trackCount":"2364"}]}}
You need to access the first artist before grabbing the id (since it's an array) like this:
var artisttype = Artists[0].id;
It would be better if you could change the JSON to always return an Array, even with one result...unfortunately some platforms don't do this, for reasons beyond my comprehension.
for(var propertyname in responseData){
//will loop through the different elements in your json array
alert(responseData[propertyName]); //will output the valueof each element
}
You're right that this is problematic, and to be honest it sounds like the "other end" that's sending you the JSON is being inconsistent.
The problem is that when there are multiple items they're sending you an array for the id property, and when there's a single item they're just sending you a simple value (e.g. an integer). Ideally, when there is a single item you should be sent a single-item array - this would let you use the same array-based parsing code every time.
If you can't convince them to change what they're sending you, though, then the best bet is simply to do what you're currently doing; see if Artists.id is defined, use it if so, else fall back to accessing id as an array.
However, if more than 1 result is returned Artists.id; will return "undefined". So I need to change it to this: Artists.id[0];
this cannot be Artists.id should be "object" not undefined if Artists.id[0] exists. Maybe it is as stated Artists[0].id ? and if so you could test typeof(Artists) == typeof([])