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?

4
  • 6
    "How would I iterate through the items in the actual order?" - there's no actual order. JS object keys are conceptually unordered. Commented Jun 9, 2013 at 12:48
  • 1
    What's "actual order" in an un-ordered data structure? Commented Jun 9, 2013 at 12:48
  • @FabrícioMatté — "Conceptually unordered". So this is just a fundamental difference between JS and something like PHP? Commented Jun 9, 2013 at 12:50
  • 1
    @Dominic I said "conceptually" as there's no specification regarding object keys ordering, though browsers tend to follow some enumeration rules. Commented Jun 9, 2013 at 12:52

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

8 Comments

@roasted true, but for plain arrays I prefer to use the plain loop, no need for a key.
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).
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 which was true until not long ago), but this is just implementation trivia. =]
@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.
@ShadowWizard Smart! I wouldn't have thought of doing it quite like that and it's perfect for my use case. Thanks again!
|
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.