Benno Benno - 3 months ago 8
jQuery Question

Sorting JSON Object

Having a problem trying to sort a JSON object. Basically, people can add products in any random order to our order form, but the order it shows in the summary needs to be how we want them to be positioned (not the order they select them), so thats why I need to sort by 'id' (or we'll sort by a 'pos' field later)

Essentially, I need to sort by the id ascending. 1,2,103 instead of 2,103,1

I seem to be having issues because the index into the individual objects are numbers (or just the fact that they're there...).

I need to do something along the lines of array.sort(function(a,b){ return a.id-b.id }); but I'm presuming that doesn't work because 1, its not an array (its an object), and 2, it has those pesky indexes (that i need for another part of my code)...

Any ideas????

var products = {
"2": {
"id": "2",
"price": "119",
"quantity": "1",
"thumb": "img\/store\/comp-08n.png"
},
"103": {
"id": "103",
"price": "109",
"quantity": "1",
"thumb": "img\/store\/basketballhoop.png"
},
"1": {
"id": "1",
"price": "309",
"quantity": "1",
"thumb": "img\/store\/comp-08.png"
}
};

Answer

How many items do you need in your orders? You can safely sort 10'000 items in a Javascript array without much of speed issues. Why don't you work with a real array instead?

You could even inject custom properties to it, roughly something like

var products = [...];

products.findById = function(id) {
   for (var i=0, len=this.length; i<len; i++) {
      if (id == this[i].id) return this[i];
   }
   return null;
};

alert( products.findById(103).price );   // -> 119

and add predefined sorters like

products.sortById = function() {
    this.sort(function(a,b) {
        return a.id - b.id;
    });
};

products.sortById();   // sort array by product id

** EDIT **

On your PHP side, you might have something like :

$products = array(
    2 => array( 'id' => 2, ... ),
    103 => array( 'id' => 103, ... ),
    1 => array( 'id' => 1, ... ),
);

// get a JSON array
$jsonArray = json_encode(array_values($products));

will return what you need.

** NOTE **

You should not explicitly set indexes when adding new items in your array. Use the array's push function, like

products.push({id:123, price:200.49, quantity:1, thumb:'/path/to/file'});

Removing an item is a bit tricky, however, something like :

products.removeById = function(id) {
   for (var i=0, len=this.length; i<len; i++) {
      if (id == this[i].id) return this.splice(i, 1)[0];
   }
   return null;
};

products.removeById(123);    // -> returns the removed element! or null if nothing was removed

See demo here (use Chrome developper tools for console output).