Maintaining array order in Javascript

I am new to JavaScript and I am having trouble working with my array, I want my array ordered how I explicitly write it and not how JavaScript decides it wants it.

If we have a array

var array = {
    0: 'zero',
    4: 'four',
    2: 'two'
};

When I choose to display this in the console, or iterate over it, Its reordered like this

array = {
    0: 'zero',
    2: 'two',
    4: 'four'
};

I have tried 2 loops so far, The for loop, and also the for loop with the in statement. Both work according how I assumed they would as they use a key and work there way up/down, making order I specify is absolutely useless.

How can I write/print/work with my array as its ordered, In other languages such as PHP its as simple as

$array = array(
    0 => 'zero',
    4 => 'four',
    2 => 'two'
);

foreach($array as $key => $value)
    echo $key ."\n";

This would output

0
4
2

Thanks in advance.

Answers


You're using an object {}, not an array []. Objects have no explicit order, where Arrays do. That's why you're having your problem. Change your {} to [] and you'll be fine. You could even use an array of objects.

var array = [
    {0: 'zero'}, 
    {4: 'four'}, 
    {2: 'two'}
];

Looping over that like so

for(var i = 0; i < array.length; i++){
  console.log(array[i]);
}

Gives us our normal order.

Object {0: "zero"}
Object {4: "four"}
Object {2: "two"} 

Another Edit: The problem is you're trying to have an array that has properties and values just like an object, without using an object, {property: value} - that can't really be done with an array. To loop over an array like you want, it's as simple as

var arr = [1,2,3]

and

for(var i = 0; i < arr.length; i++){
  console.log(i) //1,2,3
}

but the problem, like mentioned above, is you want more complex arrays which you simply can't do.


You need to understand what an Array and what an Object are, they are fundamentally different things and do not behave the same.

Array

Arrays are list-like objects whose prototype has methods to perform traversal and mutation operations. Neither the length of a JavaScript array nor the types of its elements are fixed. Since an array's size length grow or shrink at any time, JavaScript arrays are not guaranteed to be dense. In general, these are convenient characteristics; but if these features are not desirable for your particular use, you might consider using typed arrays.

Examples of an Array, note the magical length property, the values assigned to an Array are always found at their indexed locations; index is from 0 to 2^32 - 1

// dense arrays
var array1 = [1, 2, 3];

array1.length === 3;
array1[0] === 1;

var array2 = [];

array2[0] = 1;
array2[1] = 2;
array2[2] = 3;

array2.length === 3;
array1[1] === 2;

var array3 = [];

array3.push(1);
array3.push(2);
array3.push(3);

array3.length === 3;
array3[2] === 3;

// and a sparse array
var array4 = [];

array4[0] = 1;
array4[2] = 2;
array4[4] = 3;

array4.length === 5;
array4[1] === undefined;

Iterating an array for

var array = [1, 2, 3, 4, 5];

for (var index = 0; index < array.length; index += 1) { // counts from (index) 0 to 4
    console.log(index, array[index]); // outputs 0 1 \n 1 2 \n 2 3 \n 3 4 \n 4 5
}

Object

An object is a collection of properties, and a property is an association between a name and a value. A property's value can be a function, in which case the property is known as a method. In addition to objects that are predefined in the browser, you can define your own objects.

Examples of an Object, there is no magical length property.

var object1 = {
    'zero': 1,
    'one': 2,
    'two': 3
};

object1.zero === 1;

var object2 = {);

object2['zero'] = 1;
object2['one'] = 2;
object2['two'] = 3;

object2.one === 2;

var object3 = {);

object3.zero = 1;
object3.one = 2;
object3.two = 3;

object['two'] === 3;

Iterating (enumerating) an object for..in

var object = {
   one: 0,
   two: 1,
   three: 2
};

for (var property in object) {
    if (object.hasOwnProperty(property)) { // make sure the property belongs to object
        console.log(property, object[property]); // outputs (not necessarily this order)
                                                 // three 2 \n two 1 \n one 0
    }
};

If you are trying to maintain an ordered Object, then this is not how Javascript works and iteration (enumeration) of an object is arbitrary. There are techniques that you can use to iterate (enumerate) an Object in a known order. This requires that you keep an ordered list of properties in an array and use the array in the iteration process.

var object = {
   'c': 1,
   'z': 2,
   'b': 3,
   'a': 4
}

var propertyOrder = ['c', 'z', 'b', 'a'];

for (var index = 0; index < propertyOrder.length; index += 1) {
    console.log(index, propertyOrder[index], object[propertyOrder[index]]); // outputs 0 c 1 \n 1 z 2 \n 2 b 3 \n 3 a 4
}

I don't get it. What makes you think that 0, then 4, then 2, is in any form or shape "in order"?

However, apparently what you want is to keep the number and the string together, in the order that you specify.

Your mistake, if you'll excuse me for perhaps sounding a bit harsh, is that you seem to think that you can use indices or member names to be both a means to access data and part of the data itself.

You can't, and you shouldn't. An index is an index, a name is a name, and data is data [1].

Here are two implementations of keeping your numbers and strings together:

var pairs = [
    [0, "zero"],
    [4, "four"],
    [2, "two"]
];
for (var index in pairs) {
    alert(pairs[index][0] + ": " + pairs[index][1]);
};

For this one, I keep the pairs of numbers and strings together in arrays of their own: the numbers at position 0, the strings at position 1. I store these arrays in pairs.

Then I iterate over array with for/in, which, in each iteration, gives me an index of my pairs array.

I then use that index to access the right sub-array in pairs, and get the number from position 0 and the string from position 1.

var pairs = [
    {number: 0, string: "zero"},
    {number: 4, string: "four"},
    {number: 2, string: "two"}
];
for (var index in pairs) {
    alert(pairs[index].number + ": " + pairs[index].string);
};

This one works exactly the same, except of storing the pairs in arrays, I store them in objects.

This has the added bonus of better readability inside the for loop: pairs[index][0] and pairs[index][1] do not really convey a clear meaning. It tells us nothing more than, "of the pair with the given index, get items 0 and 1".

However, pairs[index].number and pairs[index].name are much clearer: "of the pair with the given index, give me the number and the name."

_

Footnotes:

[1a] A number is a number: my bank account number is just that: a means to identify my bank account. It doesn't convey any meaning as to my name, my PIN, or the balance on my account -- all attributes that would qualify as data belonging to my bank account.

[1b] A name is a name: my name is just a name. When you're talking about me, you can use my name to refer to me, so that others know whom you are talking about. My name does not convey any information about my hobbies, my SSN, or what brand of car I have -- all attributes that would qualify as data that would describe certain aspects of me. (However, by convention, you can often tell a person's gender by their name)


Need Your Help

shell script in android gives [: not found

android linux shell sh

I have this script which works on my linux machine

How to config git to pull from http and push through ssh in one 'remote'?

git authentication git-push git-pull

Pulling from http to escape authentication(so I don't need to type password if I'm not using ssh.keygen).