1

I just realized I am having a malfunction in my overall web app and it's coming down to a for loop that is reordering my object/array.

I am retrieving an associative array (object) via AJAX. I can check it's structure upon return and it is correct. For example:

48 => Value1
50 => Value2
49 => Value3
51 => Value4

But, when I loop through it, the for loop reorders the object. This is because the assoc keys are numeric. They represent numeric IDs froma database. I didn't know javascript would choke on them and try to turn them into basic array keys in numeric order. So, it spits out as:

48 => Value1
49 => Value3
50 => Value2
51 => Value4

How can I loop through the object in the order I build it in? Do I have to build the object with strings as keys? Like "ID22" replacing 22. Or is there some way to force javascript to loop in a specific order?

Thanks! Matt

Mattaton
  • 219
  • 1
  • 8
  • I usually use ["_" + i] so I prevent any confusions. Plus in some languages (php??) adding the index 49 and then 51 will feed automatically index 50, which I'm not so happy about... Also, as commented many times here in SOverflow, associative arrays are not proper technically speaking in javascript. One should use objects and properties if I recall correctly. – Sebas Mar 06 '13 at 20:46
  • possible duplicate of [Elements order in a "for (… in …)" loop](http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop) – Aaron Mar 06 '13 at 20:50
  • Thanks, Sebas. These are objects, actually. I just knew objects were javascript's answer to associative arrays (ala languages like php), so I called it that with "object" in parens. :-) – Mattaton Mar 06 '13 at 21:04

3 Answers3

1

There is no way to iterate JavaScript object in specific order, because JS object is unordered.

The best way to solve this problem - create 1 object and one array to keep order:

var values = {
  48: "Value1"
  50: "Value2"
  49: "Value3"
  51: "Value4"
}
var order = [48, 50, 49, 51] //put proterty id here to keep order eg. [51, 50, 49, 48]
Silver_Clash
  • 389
  • 1
  • 7
  • Thanks! Now I'm just trying to figure out how to package all this so it works for the php side and the javascript side. Instead of passing one php array (JSON encoded and then eval'ed by JS) back, I have to pass an array and an object back. I'll have to rework some things. – Mattaton Mar 06 '13 at 21:17
0

This is only really a problem with Chrome, they have a bug for it but it's a "Won't Fix" for the sake of internal efficiencies.

The best way I've found to get around this problem is to changing using an object:

{
  48: "Value1"
  50: "Value2"
  49: "Value3"
  51: "Value4"
}

to instead an array like so:

[
  {id: 48, value: "Value1"},
  {id: 50, value: "Value2"},
  {id: 49, value: "Value3"},
  {id: 51, value: "Value4"}
]

It ends up being much more clean than the alternative workaround (which is as you originally suggested)

Doug
  • 3,262
  • 1
  • 22
  • 30
  • array solves the issue, but there is a new problem, you can not access the object by id – Silver_Clash Mar 06 '13 at 21:00
  • That is the main disadvantage of it, I tend to use an objById function which just loops for value `function objById(arr, id){for (var x=0; x – Doug Mar 07 '13 at 14:01
0

I believe you're using for…in to retrieve your key and value.

As the link above says, and as it's specified in ECMAScript specs, "The mechanics and order of enumerating the properties (step 6.a in the first algorithm, step 7.a in the second) is not specified."

It means, you can't rely at all on the order you will get via for…in or Object.keys. If the order is important to you, you have to store the order's index somewhere, and sort the data by that property. You can't use a mere Object like that.

ZER0
  • 22,173
  • 4
  • 45
  • 51