Cristian
Cristian

Reputation: 1478

Foreach in javascript alter the secuence of my array

I've a question about the foreach in javascript

I've the following array in javascript:

puntos":{"2":"punto dos","3":"punto tres","4":"punto cuatro","5":"punto cinco","1":"punto uno"}

If I wanna do a foreach I use the following:

for (var k in puntos){
    if (puntos.hasOwnProperty(k))
    {
        console.log("Key is " + k + ", value is" + puntos[k]);
    }
}   

The secuence:

puntos":{"2":"punto dos","3":"punto tres","4":"punto cuatro","5":"punto cinco","1":"punto uno"}

The output is :

Key is 1, value ispunto uno
Key is 2, value ispunto dos
Key is 3, value ispunto tres
Key is 4, value ispunto cuatro
Key is 5, value ispunto cinco

My Question is why when I iterate over the array (puntos) the foreach alter the secuence of my array?

The secuence:

puntos":{"2":"punto dos","3":"punto tres","4":"punto cuatro","5":"punto cinco","1":"punto uno"}

The expected output

Key is 2, value ispunto dos
Key is 3, value ispunto tres
Key is 4, value ispunto cuatro
Key is 5, value ispunto cinco
Key is 1, value ispunto uno

Upvotes: 0

Views: 94

Answers (2)

joeytwiddle
joeytwiddle

Reputation: 31305

If you really want them in order, you can use non-numerical keys like this:

var puntos = {"p2":"punto dos","p3":"punto tres","p4":"punto cuatro","p5":"punto cinco","p1":"punto uno"};

Although the ECMAScript spec says there is no guarantee of the order of object properties, in reality all the engines retain the order, unless you use numerical keys, in which case some engines will sort the keys numerically as you have noticed.


An alternative way to store them in a real Array but with out-of-order keys would be to use an array of objects:

var puntos = [
    {
        key: "2",
        value: "punto dos"
    },
    {
        key: "3",
        value: "punto tres"
    },
    {
        key: "4",
        value: "punto cuatro"
    },
    {
        key: "5",
        value: "punto cinco"
    },
    {
        key: "1",
        value: "punto uno"
    }
];

Upvotes: 0

eithed
eithed

Reputation: 4349

An interesting "why?".

The object you're creating as:

var a = {"puntos":{"2":"punto dos","3":"punto tres","4":"punto cuatro","5":"punto cinco","1":"punto uno"}};

will get the keys reordered automatically:

console.log(a)

Object {1: "punto uno", 2: "punto dos", 3: "punto tres", 4: "punto cuatro", 5: "punto cinco"}

But why does it happen?

Googling - there'se a mention of Chrome issue here, where the genesis of this behavior is discussed. As such browsers indeed don't respect the ordering of elements within objects, and even different version of the same browser can produce different results, simply because there's no ECMAScript standard regarding such ordering.

Now - what's the situation currently - from the tested browsers, IE11, Chrome, Firefox, Opera, all of them follow the same pattern of reordering numerical indexes. All also follow the "do not reorder" literal indexes.

And - what to do:

  • if you're retrieving the given set from the database, and then serializing, you can (I guess) easily make indexes to be literal (as - "_1" or "01")
  • if you're given a string which then you're parsing via JSON.parse method, you can still replace the numbers using .replace(/"(\d)*":/g, function(){ return '"_'+arguments[1]+'":' })
  • if you're manipulating JS object, then, sadly there's nothing you can do.

Upvotes: 1

Related Questions