1

I have a simple, maybe a little dumb question regarding javascript associative arrays. Following is my problem:

var testArr = [];
testArr["0000"] = "00000 - COST CENTER - BALANCE SHEET";
testArr["0017"] = "0017 - Test Team";
testArr["00033"] = "00033 - Test Team ";
testArr["87210"] = "87210 - OFFICE OF THE PRESIDENT";

After these lines of code, testArr automatically sorts and shows like this:

testArr.87210 = "87210 - OFFICE OF THE PRESIDENT";
testArr.0000 = "00000 - COST CENTER - BALANCE SHEET";
testArr.0017 = "0017 - Test Team";
testArr.00033 = "00033 - Test Team ";

In my case 0000 is supposed to be the first value and default. But due to this it is making 87210 as default. How can I overcome this?

EDIT : When I see the testArr in debugger window, I see something like the following. I am not able to upload image but please follow this. Thanks very much for your help. Much appreciated!!

 testArr
       [87210] "87210 - OFFICE OF THE PRESIDENT";
       [prototype]  
       0000    "00000 - COST CENTER - BALANCE SHEET";
   0017    "0017 - Test Team";
   00033   "00033 - Test Team ";

I am not quite following why it is happening. The keys I am putting is "0000" not 0000. So in effect it should be a string right. Please explain

harimothu
  • 41
  • 5
  • 1
    JavaScript objects are not sorted. Possible duplicate of [Sort JavaScript object by key](http://stackoverflow.com/questions/5467129/sort-javascript-object-by-key) and [Sorting a JavaScript object](http://stackoverflow.com/questions/1359761/sorting-a-javascript-object) – Matt Ball Jul 12 '13 at 19:45
  • What you have is an array with properties, not an associative array. properties are not sorted. – Kevin B Jul 12 '13 at 19:46
  • I understand the sort by key in javascript object. But here it is entirely different thing I think. – harimothu Jul 12 '13 at 20:36
  • var testArr = []; testArr["\"0000\""] = "00000 - COST CENTER - BALANCE SHEET"; testArr["\"0017\""] = "0017 - Test Team"; testArr["\"00033\""] = "00033 - Test Team "; testArr["\"87210\""] = "87210 - OFFICE OF THE PRESIDENT"; Works why?. What is the difference? – harimothu Jul 12 '13 at 20:36
  • @harimothu: *"Works why?. What is the difference?"* It only *seems* to work. As already mentioned, the properties of objects are not sorted, so the order you get is arbitrary and can differ from browser to browser. – Felix Kling Jul 12 '13 at 20:59
  • It doesn't seem to be arbitrary. Because all the time I am getting 87210 on top of all other values. – harimothu Jul 12 '13 at 21:15
  • @harimothu It won't be arbitrary when you test in a single Javascript engine, but if you try other browsers or engines, they can all implement the internal order their own way since the Javascript standard explicitly states that the order of Javascript object keys is not defined. – Paul Jul 12 '13 at 21:17
  • @harimothu An object is by definition an unordered collection of (key,value) pairs, whereas an array is an ordered collection of values associated with an index (the key is used to determine order). – Paul Jul 12 '13 at 21:21
  • Thanks a lot. I got it. It is really weird, we had this code in our PROD for so long without any probs but for some reason suddenly default values (which should be the first ones) seemed to be different. After inspecting it, I came to this.o_O – harimothu Jul 12 '13 at 21:31
  • No problem. A lot of code sometimes works through a lot of testing, but if it's not fully correct it could still break unexpectedly. It's hard to catch that sort of thing when it stands up to all your tests at the time. btw, If you want to reply to someone on StackOverflow in a comment, you can prepend their name with an `@` symbol like `@Paulpro`. That way they get a notification of your comment. – Paul Jul 14 '13 at 18:08

2 Answers2

4

Because of the leading 0's you have a Javascript object rather than a Javascript array. Javascript objects don't have an order. They are a key->value map. You can convert your values to numbers and then have a sparse array instead:

var testArr = [];
testArr[+"0000"] = "00000 - COST CENTER - BALANCE SHEET";
testArr[+"0017"] = "0017 - Test Team";
testArr[+"00033"] = "00033 - Test Team ";
testArr[+"87210"] = "87210 - OFFICE OF THE PRESIDENT";

// Results in:

[
     0: "00000 - COST CENTER - BALANCE SHEET",
    17: "0017 - Test Team",
    33: "00033 - Test Team ",
 87210: "87210 - OFFICE OF THE PRESIDENT"
]

If you need to maintain the leading '0's, or if your keys are not necessarily always numeric, you should use an array of objects instead:

var testArr = [];
testArr.push({id: "0000", name: "00000 - COST CENTER - BALANCE SHEET"});
testArr.push({id: "0017", name: "0017 - Test Team"});
testArr.push({id: "00033", name: "00033 - Test Team "});
testArr.push({id: "87210", name: "87210 - OFFICE OF THE PRESIDENT"});

Then you maintain the order and can loop through in order like this:

for(var i = 0; i < testArr.length; i++){
    console.log(testArr[i].id + ': ' + testArr[i].name);
}
Paul
  • 139,544
  • 27
  • 275
  • 264
0

Depending on how you need to use it, you could also do something like this:

var testArr = [];

testArr.push({ id: "0000", value: "00000 - COST CENTER - BALANCE SHEET"});
testArr.push({ id: "0017", value: "0017 - Test Team"});
testArr.push({ id: "00033", value: "00033 - Test Team "});
testArr.push({ id: "87210", value: "87210 - OFFICE OF THE PRESIDENT"});

Your array would stay in the order you created it, and your IDs would stay intact. You would of course lose the ability to access the item like an associative array using the id.

Edit in response to your comment:

Objects in javascript are the same thing as associative arrays. So when you do this:

testArr["0000"] = whatever

It's exactly the same as

testArr.0000 = whatever

Given that, you can see why there's no sorting. Properties in an object have no sort order.

What I'm doing differently is pushing objects into an array (an actual array, not an associative array/object), so the indexing is done as 0, 1, 2 (since it's an array), and the order is preserved.

Jason P
  • 26,984
  • 3
  • 31
  • 45
  • The followins works fine though. I don't understand the difference! var testArr = []; testArr["\"0000\""] = "00000 - COST CENTER - BALANCE SHEET"; testArr["\"0017\""] = "0017 - Test Team"; testArr["\"00033\""] = "00033 - Test Team "; testArr["\"87210\""] = "87210 - OFFICE OF THE PRESIDENT"; – harimothu Jul 12 '13 at 20:34
  • @harimothu edited to respond. – Jason P Jul 12 '13 at 20:40