Fetch values of key-value in array of objects - javascript

I'm trying to display the values of all key-value pairs in an array of objects. I've tried several methods, for example http://jsfiddle.net/4Mrkp/, but I can't seem to get it to work on my data.
The data, I want to display the car makes only:
{
"response":{
"status":"200",
"messages":{},
"milliseconds":"2"
},
"input":{
"provinceid":{},
"supplierid":"12345678",
"statusid":{ }
},
"output":{
"count":"7",
"list":{
"make":[
{"name":"Alfa Romeo"},
{"name":"Audi"},
{"name":"BMW"},
{"name":"Chevrolet"},
{"name":"Chrysler"},
{"name":"Citroen"},
{"name":"Dacia"}
]
}}
}
My code so far, this displays the word make:
function display_makes(obj)
{
document.getElementById("temp-id").innerHTML =
Object.keys(obj.output.list.make).forEach(function(key){
document.write(key);});
}
So next step is to fetch the values of each element of make, but how? Any thoughts?

Don't use Object.keys on obj.output.list.make because it's an array, use:
obj.output.list.make.forEach(function(obj) {
console.log(obj.name);
});

You may use underscoreJS for manipulating the JSON.
var make = _.map(json_object.output.list.make,function(make) {
document.write(make.name);
return make;
})
This make variable will contain values in key-value pair.

It is easier than you think. Just iterate over the array and forget about the rest:
object.output.list.make.forEach(function(item){
document.write(item);
});
You are working with the array therefore you do not need at all the Object.keys()

Related

Using Underscore.js to filter and merge json

I have a use case where I need to use underscore.js to filter a JSON. For example
{"test":{
{ key: 1,country:USA,product:A,price:200}
{key: 1,country:USA,product:B,price:200}
{key: 1,country:UK,product:B,price:300}
}
}
I have multiple dimensions for same key. I need to get the output as follows when i filter USA
{"test":{
{ key: 1,country:USA,price:400}
}
}
and when I filter for product B
{"test":{
{ key: 1,product:B,price:500}
}
}
I'd like to implement this using underscore.js as I believe it is fast compared to pure JS options.
I'm assuming you have a typo and test contains an array of objects:
var filtered = JSON.parse(jsonString).test.filter(function(item) { return item.country == 'USA' });
var total = 0;
filtered.forEach(function(item) {
total += item.price
});
Don't worry about speed, this would be a micro-optimization, which is not recommended.
Firstly, try to use underscore _.filter to apply searching with your criteria like product or country.
Then do an aggregation based on result from filter by simply use _.each function.
Finally, you can manipulate your result in _.map function.
I posted jsfiddle link here, it might help you
jsfiddle.net/zusquang/39os1854/
I'm doing hope this help.

sortBy keeping key name

I'm trying to sort an object but can't seem to keep the key name of each object after sorting.
Here is the sample json I'm sorting on
series_data: {
embeded: {
objectNameA: {
item: {
last:{reportdate:2014-10-05, trend:=, change:0, value:0},…},
first: {reportdate:2013-01-06, trend:?, change:null, value:0},
high: 1,
low: 0,
median: 0.043478260869565216,
series: [{reportdate:2013-01-06, trend:?, change:null, value:0},…]
},
objectNameB: {…}
I need the objectName becasue it's used in my templates to describe everything else.
here is how I am sorting the data
var items = _.sortBy(series_data.embeded, function(series, index) {
return series.cd.last.value
}).reverse();`
This returns 0:{…}, 1:{…}, 2:{…}, when I need it to be objectNameA:{…},objectNameB:{…}.
OR better yet
0:{objectNameA:{…},…}, 1:{objectNameB:{…},…}
How do I keep or add the objectName while sorting in order from highest to lowest?
I don't think that you can do this with a single call to _.sortBy().
However, you can accomplish it in two steps:
call _.sortBy() and assign the key of each object as a property
call _.each() on the sorted array to get the desired object structure
Here is an example JSBIN
The underlying problem is that objects are unordered collections of properties.
I achieved this by setting a key property on each object within the _.sortBy() - not ideal but one solution
_.sortBy(object, function(item, key) {
item.key = key;
return item.sortattribute;
});

Use pop() with JavaScript Associative Arrays

How can I do something like the following in JS? I would like to imitate .pop() on an object rather than an array.
var deck = {
'cardK' :'13',
'cardQ' :'12',
'cardAJ':'11'
};
var val = deck.pop();
console.log("Key" + val.key );
console.log("Value" + val.val );
It seems like it's not possible.
.pop is only available on an array. In JavaScript, objects (which are essentially associative arrays) are not ordered like an array, so there is no .pop method.
You could use an array:
var deck = [
{ key: 'cardK', val: 13 },
{ key: 'cardQ', val: 12 },
{ key: 'cardAJ', val: 11 },
];
var val = deck.pop();
console.log('key: ' + val.key);
console.log('aa: ' + val.val);
As suggested by other answers, the best solution here might be to use an array of objects. However you could also create your own pop function that removes a key from an object, for example:
function pop(obj) {
var key = Object.keys(obj).pop();
var result = {key: key, val: obj[key]};
delete obj[key];
return result;
}
var val = pop(deck);
You could add a similar pop function to Object.prototype so that you could do deck.pop(), but I would strongly recommend against that type of design.
You are right, it's not possible. See objects as maps or hash tables, rather than "associative arrays". The properties don't have an order and thus a method such as .pop would not make sense (unless of course it would remove a random property, like Python's dictionaries).
If you want to to use .pop and val.key and val.val, you have to create an array of objects instead:
var deck = [
{key: 'cardK', val: '13'},
{key: 'cardQ', val: '12'},
{key: 'cardAJ', val: '11'}
];
As I'm sure you know, .pop is a prototypal Array method, so you can't use it with Javascript objects.
Calling .pop on an array will remove the last element from the array. However, there isn't a "last" key-value pair with objects, as their order is not ever guaranteed. Despite this, if you don't care about order, you could implement a .pop-like function for use with objects, though, again, it wouldn't remove and return the final key-value pair.
Something like this should do the trick:
function pop(obj) {
for (var key in obj) {
var val = obj[key];
delete obj[key];
return {
'key' : key,
'val' : val,
};
};
};
Combined with your code:
var val = pop(deck);
console.log('key: ' + val.key);
console.log('aa: ' + val.val);
When working with this structure, which can be thought of as an associative array, you need to use different techniques. Things like pop(), slice() and even .length will not work as they do with numeric keyed arrays.
I use string keyed object arrays when searching for the key/value pair needs to happen fast.
Here's a jsPef I just created which shows the benefit of your array structure:
http://jsperf.com/bmcgin-object-array-tests (keep in mind the performance goes way up as the array gets bigger)
Also keep in mind the value can be a number, a string, an array, a function, an object ect...

Split one JSON return into several objects

So, I've been looking at this for a couple hours and am out of ideas. My app is returning a single JSON object, and I need to parse the 4 data sets out of it and make 3 charts and a table. For the life of me I can't figure out how to "extract" each part. The JSON looks like:
{
"allele":{
"12426597":{
"??":4,
"CC":3,
"TT":4,
"CT":12
},
"878198":{
"??":4,
"AA":1,
"AC":15,
"CC":3
},
"6447271":{
"??":4,
"GG":14,
"AG":5
}
},
"haplo":{
"CT,AG,AC":3,
"TT,GG,AC":1,
"CC,GG,CC":1,
"TT,AG,CC":1,
"TT,GG,CC":1
},
"exercise":"p1"
}
I need to grab the data just for the three key's/IDs (12426597,878198, 6447271) and make one bar chart for each of those (requiring a data transformation <== see). Then I need to plug it into Highcharts...their API calling for an ordered arrays for the keys and values.
I thought about first making an array of the IDs:
var snpsObj = data.allele_frequency; // data returned from $.getJSON
var snpList = [];
for (prop in snpsObj) {
if (!snpsObj.hasOwnProperty(prop)) {
continue;
}
snpList.push(prop);
}
Which does get me the wanted array. And then accessing the "sub" keys like:
snpsObj.snpList[0];
...to return hopefully, something like:
{
"CC" : 23,
"CT" : 36,
"TT" : 12,
}
But that doesn't work at all. The most I could get was a return of something like:
allele_frequency : [object Object ]
I know there's something basic I'm just forgetting in my head-cold-fogged mind... Any suggestions?
Highcharts needs the keys and labels formatted in arrays, like:
categories: ['C', 'T']
data: [ 3, 9] // C=3, T=9
I think you want to access
snpsObj[ snpList[0] ]
by using bracket notation, snpsObj.snpList[0] would try to get the "snpList" property of your snpsObj object.
Btw, instead of your for-in-loop to create the array with property names, you might want to use Object.keys (even if you need to shim it to support old browsers).

Trouble Sorting JSON

I have a JSON object like the following:
{"Data": {
"290": {
...
}
"300": {
...
}
"281": {
...
}
}
}
How would I sort this JSON based on the top container keys (i.e. "290", "300", "281")?
Edit: So I used
$.getJSON('current/csf.txt', function(data) { arr = data["Data"]; }
And it sorted them based on the key. Why did this happen?
You've tagged this "JavaScript" so I assume you mean "A JavaScript object generated from this JSON".
In which case:
Loop over the property names (with a for in loop).
Use them to populate an array.
Sort the array.
Use the array as a map.
(You can't store ordered data in an object).
If you want to store the results in JSON, then you will need to change your data structure (and use an array (of objects)). Objects are explicitly unordered.
Your structure is wrong, it should be something like:
{
"Data": [
{
"id": "290"
},
{
"id": "300"
},
{
"id": "282"
}
]
}
Objects are for unordered data. Use arrays for ordered data. And the array is really easy to sort here:
obj.Data.sort(function(a,b){
return a.id - b.id;
});
You can convert to this structure like so:
function copyProps(dest, src) {
for (var key in src) {
dest[key] = src[key];
}
return dest;
}
var newData = [];
for (var key in obj.Data) {
newData.push(copyProps({
id: key
}, obj.Data[key]));
}
I agree with Amberlamps comment, you shouldn't be trying to sort the keys of an object, but if you wanted to for some reason you might take a look at underscore.js's sortBy method
Even if you COULD sort object attributes, there's no guarantee that you could read them back in sorted order. In Javascript, object attributes are not stored in a specific order; an object simply has attributes.
You cannot use array index notation to access object attributes, so the notion of sorting object attributes by key is moot.

Categories

Resources