1

The object

var obj = {
   uniquestring1:
   {
       obj1: 'content',
       obj2: 'content'
   },
   uniquestring2:
   {
       obj1: 'content'
   }
}

So i need to sort the object by number of the elements contained by the first parent element. The use of .sort function is not a sollution for me because i need to maintain the index assosiaction which array's dont keep.

The result should be:

var obj = {
   uniquestring2:
   {
       obj1: 'content'
   },
   uniquestring1:
   {
       obj1: 'content',
       obj2: 'content'
   }
}
Joe
  • 80,724
  • 18
  • 127
  • 145
keepwalking
  • 2,644
  • 6
  • 28
  • 63
  • 1
    You can't sort an object's properties because they are not an ordered array. Perhaps you want to iterate over the properties in a certain order? – js1568 Aug 30 '11 at 18:17
  • implement some sorting algorithm, don't use jquery .sort if it doesn't fit your case. http://stackoverflow.com/questions/220044/which-sort-algorithm-works-best-on-mostly-sorted-data – Marek Sebera Aug 30 '11 at 18:18

2 Answers2

4

Javscript objects don't have a sort order so they can't be sorted. To sort, you must have an array somewhere and I see no array in your code.

Object keys have no defined order.

  • If you only need ordered access, use an array.
  • If you only need keyed access, use an object.
  • If you need access by both, you can use a parallel array, but this is a pain unless the data is not changing.

You could do a one-time creation of a parallel array that contained key references in sorted order like this:

var obj = {
   uniquestring1:
   {
       obj1: 'content',
       obj2: 'content'
   },
   uniquestring2:
   {
       obj1: 'content'
   }
}

var objOrder = [];   // sorted arrays that contains first level keys into obj
var num;
for (var i in obj) {
    objOrder.push(i);  // get all keys into the array
    num = 0;
    for (var j in obj[i]) {
        ++num;         // count items in each key object
    }
    obj[i].keyCnt = num;   // save this for later sorting purposes
}
// now sort the parallel array by keyCnt
objOrder.sort(function(a, b) {
    return(obj[a].keyCnt - obj[b].keyCnt);
});

Then, to traverse the keys in sorted order, you would do it like this:

for (var i = 0; i < sortedOrder.length; i++ ) {
    var item = obj[sortedOrder[i]];
    // do something with item here
}
jfriend00
  • 683,504
  • 96
  • 985
  • 979
2

obj is a hash not an array, so you can't sort it. For example, obj[0]; // is undefined. Now if you had this:

var obj = {
   uniquestring1:
   {
       obj1: 'content',
       obj2: 'content'
   },
   uniquestring2:
   {
       obj1: 'content'
   }
};
var arr = [],

for(var i in obj) {
    arr.push(obj[i]);
}

arr.sort(function (a, b) {
   return Object.keys(a).length - Object.keys(b).length;
})

Then that sort would work, with Object.keys

Joe
  • 80,724
  • 18
  • 127
  • 145
  • Of course i know that, that is why i've asked here for a workaround. – keepwalking Aug 30 '11 at 18:20
  • 1
    @keepwalking: why are you looking for a workaround? What's wrong with this? If you need your labels, you should wrap your objects in *yet another* object: {label: 'uniquestring1', value: { obj1: 'content', obj2: 'content' } – Joseph Silber Aug 30 '11 at 18:22
  • Keep in mind the the `.keys()` property of an object is not supported in older browsers such as IE6-IE8. – jfriend00 Aug 30 '11 at 18:28