Ok, so on a web page, I’ve got a JavaScript object which I’m using as an associative array. This exists statically in a script block when the page loads:
var salesWeeks = { '200911' : ['11 / 2009', 'Fiscal 2009'], '200910' : ['10 / 2009', 'Fiscal 2009'], '200909' : ['09 / 2009', 'Fiscal 2009'], '200908' : ['08 / 2009', 'Fiscal 2009'], '200907' : ['07 / 2009', 'Fiscal 2009'], '200906' : ['06 / 2009', 'Fiscal 2009'], '200905' : ['05 / 2009', 'Fiscal 2009'], '200904' : ['04 / 2009', 'Fiscal 2009'], '200903' : ['03 / 2009', 'Fiscal 2009'], '200902' : ['02 / 2009', 'Fiscal 2009'], '200901' : ['01 / 2009', 'Fiscal 2009'], '200852' : ['52 / 2008', 'Fiscal 2009'], '200851' : ['51 / 2008', 'Fiscal 2009'] };
The order of the key/value pairs is intentional, as I’m turning the object into an HTML select box such as this:
<select id='ddl_sw' name='ddl_sw'> <option value=''>== SELECT WEEK ==</option> <option value='200911'>11 / 2009 (Fiscal 2009)</option> <option value='200910'>10 / 2009 (Fiscal 2009)</option> <option value='200909'>09 / 2009 (Fiscal 2009)</option> <option value='200908'>08 / 2009 (Fiscal 2009)</option> <option value='200907'>07 / 2009 (Fiscal 2009)</option> <option value='200906'>06 / 2009 (Fiscal 2009)</option> <option value='200905'>05 / 2009 (Fiscal 2009)</option> <option value='200904'>04 / 2009 (Fiscal 2009)</option> <option value='200903'>03 / 2009 (Fiscal 2009)</option> <option value='200902'>02 / 2009 (Fiscal 2009)</option> <option value='200901'>01 / 2009 (Fiscal 2009)</option> <option value='200852'>52 / 2008 (Fiscal 2009)</option> <option value='200851'>51 / 2008 (Fiscal 2009)</option> </select>
…with code that looks like this (snipped from a function):
var arr = []; arr.push( '<select id=\'ddl_sw\' name=\'ddl_sw\'>' + '<option value=\'\'>== SELECT WEEK ==</option>' ); for(var key in salesWeeks) { arr.push( '<option value=\'' + key + '\'>' + salesWeeks[key][0] + ' (' + salesWeeks[key][1] + ')' + '<\/option>' ); } arr.push('<\/select>'); return arr.join('');
This all works fine in IE, FireFox and Opera.
However in Chrome, the order comes out all weird:
<select id='ddl_sw' name='ddl_sw'> <option value=''>== SELECT WEEK ==</option> <option value='200852'>52 / 2008 (Fiscal 2009)</option> <option value='200908'>08 / 2009 (Fiscal 2009)</option> <option value='200906'>06 / 2009 (Fiscal 2009)</option> <option value='200902'>02 / 2009 (Fiscal 2009)</option> <option value='200907'>07 / 2009 (Fiscal 2009)</option> <option value='200904'>04 / 2009 (Fiscal 2009)</option> <option value='200909'>09 / 2009 (Fiscal 2009)</option> <option value='200903'>03 / 2009 (Fiscal 2009)</option> <option value='200905'>05 / 2009 (Fiscal 2009)</option> <option value='200901'>01 / 2009 (Fiscal 2009)</option> <option value='200910'>10 / 2009 (Fiscal 2009)</option> <option value='200911'>11 / 2009 (Fiscal 2009)</option> <option value='200851'>51 / 2008 (Fiscal 2009)</option> </select>
NOTE: This order, though weird, does not change on subsequent refreshes. It’s always in this order.
So, what is Chrome doing? Some optimization in how it processes the loop?
In the first place, am I wrong to rely on the order that the key/value pairs are declared in any associative array?
I never questioned it before, I just assumed the order would hold because this technique has always worked for me in the other browsers. But I suppose I’ve never seen it stated anywhere that the order is guaranteed. Maybe it’s not?
Any insight would be awesome. Thanks.
Think of an associative array as a paper sack into which all the key-value pairs are placed. As you reach your hand into the sack to look at the pairs (such as with the for…in loop), the order that you encounter them is for all practical purposes random.
If you want to see them in a specific order, you’ll need to extract the keys into an array and sort it. Then walk across the array, using the keys you encounter to index into the associative array.