Trouble Sorting JSON - javascript

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.

Related

How to handle a nested json array to show in a table?

I have this JSON array. I am displaying data in a table. So, How should I put 'transactionData' inside the main object? i.e. I want the object as
{
completeTime: "value",
createTime: "value2",
assigneeName:"value3",
assigneeMap:"value4"
}
Since this is a JSON Array, so I need a way to iterate the array and make each of the objects as required.
I can't use the original JSON array since the object transactionData is not fixed and its keys might change. So, I don't want to hardcode any value like assigneeMap or assigneeName as it might change.
Hence, I want whatever the values in transactionData object are there, I want to insert it into my main object.
use the array.map(), something like this
results.map(x=>{
{
completeTime: x.completeTime,
createTime: x.createTime,
assigneeName: x.assigneeName || x.assigneename,
assigneeMap:x.assigneeMap || x.assigneeMap || x.yourChangedKey,
}
})
Use Array.prototype.map()
const result = arr.map(item => {
const { completeTime, createTime, data: { transactionData } } = item;
const { assigneeName, assigneeMap } = transactionData;
return {
completeTime,
createTime,
assigneeName,
assigneeMap
}
});

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

Get key values in JSON array

I'm trying to get the key values of each record in a JSON array when looping through it. Currently I have a simple JSON object like this:
"users": {
"key_11": {
"text": "11"
},
"key_22": {
"text": "22"
},
"key_33": {
"text": "33"
}
}
My current script uses the 'map' method to convert this JSON objet to a loop-able array:
var user_profiles_array = $.map(user_profiles_string, function(el) { return el; });
for (var xt = 0; xt < user_profiles_array.length; xt++) {
console.log(user_profiles_array[xt].text); //11 or 22
}
My question is, how can I get the value for e.g: 'key_11' or 'key_22'?
Thanks!
you can use Object.keys to get an array of all of your object's keys. Once you have that array, you can use Array.forEach to iterate over it as necessary:
Object.keys(usersObject).forEach(function(key, keyIndex) {
console.log("index:",keyIndex,"key:",key,"value:",usersObject[key]);
});
But!
your particular problem here is being caused by using $.map instead of JSON.parse. $.map returns an array, so of course your keys are always going to be numerical array indices - 0, 1, 2, and so on. You're not going to be able to use hash keys to find things in the array returned by $.map. Furthermore, judging by your variable names you're calling $.map on a string which is definitely not going to do what you want. Assuming you figure that part out and you somehow get a valid JavaScript object, and you still need to use $.map() for some reason, what you can do is this:
// $.map will return an array...
$.map(user_profiles_object, function(objVal, objKey) {
// ...and each item in that array will be an object with a
// property named 'key' and a property named 'val'
return {
key: objKey,
val: objVal
};
}).forEach(function(arrayObj) {
// now each item in the array created above will be an object
// created by your callback function:
console.log(arrayObj.key,":",arrayObj.val);
});
You can also rely on Js's foreach.
// JSON string must be valid. Enclose your JSON in '{}' (curly braces);
var user_profiles_string = '{ "users": { "key_11": { "text": "11" }, "key_22": { "text": "22" }, "key_33": { "text": "33" }}}';
var user_profiles_array = JSON.parse(user_profiles_string);
// For retrieval in loop, the Js foreach asigns the key to index param (i in this case).
for (i in user_profiles_array.users) {
// i is the key of the user currently iterated.
console.log('Key name is: ' + i);
// Use i as the index to retrieve array value.
console.log(user_profiles_array.users[i]);
}
// For direct retrieval using any given known key:
console.log(user_profiles_array.users['key_11']);

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;
});

Is there a way to get number of elements from object?

Let me explain in detail. I have below an object with me -
{
"OBJECT1" : {
"NAME1" : "VALUE1",
"NAME2" : "VALUE2",
"NAME3" : "VALUE3"
},
"OBJECT2" : {
"NAME4" : "VALUE4",
"NAME5" : "VALUE5"
}
}
From this object, I want to get something like number of elements in OBJECT1 = 3 and number of elements in OBJECT2 = 2. If at all this is possible using javascript.
Basically what I am trying to do is, to loop through the name value pairs available in the object dynamically so that if someone adds another element to object, I don't have to change my code.
Also any alternative is also ruled out since I am allowed to only use object in my use-case.
Without converting your object you could iterate through the object counting properties like so:
function countObjectProperties(obj)
{
var count = 0;
for(var i in obj)
if(obj.hasOwnProperty(i))
count++;
return count;
}
Expanding on why you need to use hasOwnProperty as I said in the comment below you can run into an issue where a library or browser has added methods and properties to Objects, in order to avoid counting these we check for hasOwnProperty before counting it. More details at MSDN or at Mozilla Developer Center
For JSON string that represent an object (which is your case), you cannot use any length property. you need to loop through the object (see Kristoffer S Hansen's answer).
If it represented an array, you could get the length with:
var len = arr.length;
JQuery makes it simpler:
var len = $(JSON).length;
To answer your broader goal, as specified in your question:
For looping through the properties, you can use the for..in construct:
for (var item in myobject) {
// some browsers add more properties to every object, we don't want those
if (myobject.hasOwnProperty(item)) {
do_something(item);
}
}
Assuming that myobject is the object in your question, this will loop through it and call do_something(OBJECT1) and do_something(OBJECT2); you can use the same construct to loop through the child objects:
// loop through OBJECT1 and OBJECT2
for (var item in myobject) {
// some browsers add more properties to every object, we don't want those
if (myobject.hasOwnProperty(item)) {
// loop through the item's children
for (var pair in item) {
if (item.hasOwnProperty(pair)) {
// each of the name:value pairs will be passed to this
do_something_else(item,pair);
}
}
}
}

Categories

Resources