Split one JSON return into several objects - javascript

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).

Related

Fetch values of key-value in array of objects

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()

loop through object and return value of all property arrays

I have a javascript object with a bunch of properties. In this example each property represents a piece of clothing, with a key and then a value that is an array.
var clothes = {
CLO1: ["shirt", "cotton", "white"],
CLO2: ["tie", "silk", "red"],
CLO3: ["shoes", "leather", "black"]
};
I want to loop through each one and print out the color for each piece of clothing. I'm trying to figure out the most concise way to do this. Something like this--
for (property in object) {
if (property[key]){
return (property[2])
} else { return "none";
}
Any thoughts would be really greatly appreciated. I hope this makes sense. Thanks!
Looks fine to me. Are arrays sometimes empty or null? The suggestion in the comments to remove the extra return statement is a good suggestion.
I noticed that each array has a similar structure. The first element is the type of clothing, the second element is the material and the third element is the color. You can use an object instead of an array. The advantage of using an object is that it tells you (and other programmers) more about the structure of your data. Use an array to store a collection of these objects:
var clothes = [
{ type: "shirt",
material: "cotton",
color: "white"
},
{ type: "belt",
material: "leather",
color: "none"
];
Also, instead of checking if the property "color" exists, always include "color". Set "color" to "none" if it is not relevant.
Printing out the colors looks like:
clothes.forEach(function(each) {
console.log(each.color);
});
UPDATE
I chose to always include "color" because it simplifies the procedural code. Without the data redundancy I must check to see if particular keys exist when I iterate over the properties. I usually choose to simplify the code, not the data. Philosophically, it is similar the trade-offs between dense and sparse data representations.
There is also a semantic reason always including color. What if some clothes have the property "size", but others don't. What if all the examples I look at do not have "size"? I would not know to include "size" in my procedural code.
var clothes = {
CLO1: ["shirt", "cotton", "white"],
CLO2: ["tie", "silk", "red"],
CLO3: ["shoes", "leather", "black"]
};
var print = function(obj) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
console.log(obj[property][2]);
}
}
}
print(clothes);
On each iteration of the for loop, the property variable holds the name of the property, you then have to have to index into obj to retrieve the value of the property, and then again index the second element of the array to get the colour you asked for.
This works, although I would suggest creating an structure (as suggested by #ahoffer) to hold these items.
// - Object.keys takes an object and returns an array of keys
// - forEach iterates that array
// - console.log prints it to the console
Object.keys(clothes).forEach(function (type) {
console.log(clothes[type][2]);
});
Maybe something like that?
Object.keys(clothes).forEach(function(type) {
console.log(type + ": " + clothes[type].join(', '));
});
The code above will give you this:
CLO1: shirt, cotton, white
CLO2: tie, silk, red
CLO3: shoes, leather, black

Merging two arrays with some logic in javascript

I try to merge something like (I show it in json)
[["Field1","0"],["Field2","0"],["Field3","0"]]
with
{"0":{"Name":"Foo","Lastname":"Bar"}}
when I do
$.extend({}, firstArray, secondArray);
I get in JSON
{
"0":{"Name":"Foo","Lastname":"Bar"},
"1":["Field1","0"],
"2":["Field2","0"]
}
as you can see the first array is some kind of mixed with the second. I want it to be wrapped up like this
{
"0":{"Name":"Foo","Lastname":"Bar"},
"1":[ "1": ["Field1","0"],"2":["Field2","0"]]
}
So later when I consume it I can get the field stuff as one array. Is the possible? I cannot get it to work. Any ideas?
Looks like you only need to add secondArray as a property of firstArray, but converted into an object. That can be accomplished like this:
firstArray["1"] = $.extend({}, {}, secondArray);
Now firstArray becomes:
{
"0":{"Name":"Foo","Lastname":"Bar"},
"1":{"0": ["Field1","0"], "1":["Field2","0"]}
}
I hope that's good enough.
firstarray = firstarray.concat(secondarray)

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.

difference between 2 objects/arrays

i have 2 objects, which are associated arrays from PHP in JSON. They have an structure like that´:
[object]
["green"]
['value1']=integer
['value1']=array...
["blue"]
['value1']=integer
['value1']=array...
[...]
The 1st Version of this object is loaded from webserver periodically using JSON.
By receiving this new JSON string from webserver, the current object moved to the variable "oldObj" while the new data stored into the variable "newObj".
It could be possible, that the new object will have less elements than the old object, like this:
[newObj]
["green"]
['value1']=integer
['value1']=array...
As you can see: "blue" is missing.
Now i need this elements which are part of the old Object / that means: which are missing at the new object (at this example: element "blue")
I tried the following, but without any success:
[...]
var newObj=data;
$.each (oldObj,function(i,n)
{if (newObj.i.length<1) {alert('missing: '+i);}
}
);//end foreach
Error message: "newObj.i is undefined"
According to your description, I think newObj or oldObj can be wrote as:
var newObj = {
"green": [
integer,
[array]
],
"blue": [
integer,
[array]
]
};
Is it right?
You could use :
for(p in Obj){
if(Obj.hasOwnProperty(p)){
// do something with p
}
}
to loop through the Obj's properties.

Categories

Resources