1

I have some JSON data:

{  
  "113":{"id":"113","title":"Coal","hex":"4f4f4f"},
  "116":{"id":"116","title":"White","hex":"fdfbf7"},
  "115":{"id":"115","title":"Greylead","hex":"b3b3b3"}
}

Which is in the markup on a data attribute I can access like so:

var arr = $("#element).data('arr');

And then do stuff with each item. Like so:

$.each( arr, function( index, obj ){ 
   console.log( obj.title + ' is #' + obj.hex );
}

But the order of the items in the data isn't being preserved.

$.each seems to iterate through by the leading number of each item in the data, NOT the order that items are actually in the array. I get my output in the numerical order 113, 115, 116 instead of 113, 116, 115 (which is the actual order of the items in the data).

How would I iterate through the items in the actual order?

Dominic
  • 2,367
  • 1
  • 15
  • 16

2 Answers2

5

If order matters to you, use plain array:

[
    {"key": "113", "id":"113","title":"Coal","hex":"4f4f4f"}, 
    {"key": "116", "id":"116","title":"White","hex":"fdfbf7"}, 
    {"key": "115", "id":"115","title":"Greylead","hex":"b3b3b3"}
]

Then plain loop:

for (var i = 0; i < arr.length; i++) {
    var obj = arr[i];
    console.log( obj.title + ' is #' + obj.hex );
}

Live test case.

If you want to search for item based on its key, you now have to loop over all items to find it. For better efficiency you can create additional "mapper" object:

var mapper = {};
for (var i = 0; i < arr.length; i++) {
    var obj = arr[i];
    mapper[obj.key] = obj;
}

Then to look for item based on key:

key = "115";
if (mapper[key]) {
    //exists...
}

Updated fiddle.

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
  • @roasted true, but for plain arrays I prefer to use the plain loop, no need for a key. – Shadow The GPT Wizard Jun 09 '13 at 12:57
  • plain `for` loops are some millersecondz faster (as it doesn't apply a callback creating a new execution context/function scope for each element in the array). – Fabrício Matté Jun 09 '13 at 12:57
  • 1
    Well yes, my latest benchmarks show that V8 can optimize native `for` loops to be even faster than the usual `var i = arr.length; while(i--) {}` (contrary to [popular believe](http://stackoverflow.com/a/1340634/1331430) which was true until not long ago), but this is just implementation trivia. `=]` – Fabrício Matté Jun 09 '13 at 13:01
  • @ShadowWizard Thanks! I am using the structure `"id" : { "stuff": "etc..." }` on the assumption that it would be faster (and more convenient) to get an item's details by the id; e.g., arr[113].title == 'Coal'. In your answer, is there a performance issue if I have to search all the data for an item with id of 113 instead? – Dominic Jun 09 '13 at 13:20
  • 1
    @Dominic fair point. It depends on the size of the array. In my opinion if 100 or less it's really too minor to make any difference. Otherwise, build another object which is associative array mapping each item of the plain array based on its key. If relevant let me know and I'll come with sample code. – Shadow The GPT Wizard Jun 09 '13 at 13:22
  • @ShadowWizard I've done the latter (I made a sort order associative array) because it means no changes to the rest of my code. – Dominic Jun 09 '13 at 13:28
  • @ShadowWizard That said, what would you recommend as a fast way of looking up item details by id (based on the plain array format in your answer)? – Dominic Jun 09 '13 at 13:31
  • 1
    @ShadowWizard Smart! I wouldn't have thought of doing it quite like that and it's perfect for my use case. Thanks again! – Dominic Jun 09 '13 at 13:55
0

just go this site http://json.parser.online.fr and paste this

   {  
    "113":{"id":"113","title":"Coal","hex":"4f4f4f"},
    "116":{"id":"116","title":"White","hex":"fdfbf7"},
    "115":{"id":"115","title":"Greylead","hex":"b3b3b3"}
   }

I think u will get your answer where JSON.parse maintains ORDER and eval('('+data+')') maintains INDEX.Then run a plain loop and do your other jobs.

sharif2008
  • 2,716
  • 3
  • 20
  • 34