You should never sort object properties. Browsers may optimize objects in memory by rearranging their properties, at any point in time.

Objects are like sets, designed to store unique elements without having to worry about the order.

Ordered items should be stored in arrays.

Sent from my iPhone

On Feb 4, 2010, at 18:18, Michael Fuery <[email protected]> wrote:

Hello Everyone,

I notice that Firefox seems to maintain the order of key:value pairs
in objects when iterating over them, while Safari and Chrome seem to
sort the object internally (within their respective JS engines).  I
noticed this especially when making select elements.  I store the
options as an object, then when drawing the page, I iterate over that
object making option elements.

For example, I am making a select box that lists users
alphabetically.  Users are identified in the database by an id:
var foo = new Element('select').inject($$('body')[0]);
var options = {5082:'User A', 5085:'User B', 5074:'User C'}
$H(options).each(function(name,id){
 new Element('option', {text:name, value:id}).inject(foo);
});

In Firefox the select box would present users in order: A,B,C, but in
the others, users would appear in order by id: C,A,B.  A neat function
for tackling this sort of problem would be Hash.sort.

/*
   Function: Hash.sort
       Takes {c:0, a:1, b:2} and returns [{a:1},{b:2},{c:0}]
*/
Hash.Implement({
sort:function(fn){
   var out = [],
       keysToSort = this.getKeys(),
       m = this.getLength();
(typeof fn == 'function') ? keysToSort.sort(fn) : keysToSort.sort ();
   for (var i=0; i<m; i++){
       var o = {};
       o[keysToSort[i]] = this[keysToSort[i]];
       out.push(o);
   }
   return out;
}
});
____________
Usage:

$H({'a':1,'z':2,'c':3,'b':4}).sort()

Results In:

[Object { a=1}, Object { b=4}, Object { c=3}, Object { z=2}]
______________________

Then our select box routine becomes:
var foo = new Element('select').inject($$('body')[0]);
var options = {5082:'User A', 5085:'User B', 5074:'User C'}
$H(options).sort().each(function(el){
 $each(el,function(name, id){
   new Element('option', {text:name, value:id}).inject(foo);
 });
});

_______

Ruby programmers may recognize this method (http://ruby-doc.org/core/
classes/Hash.html#M002865).

Reply via email to