10

I have an array of objects in javascript, each of which in turn has an array:

{
 category: [ 
 { name: "Cat1", elements : [ 
 { name: name, id: id } ] 
 },
 { name: "Cat2", elements : [ 
 { name: name, id: id },
 { name: name, id: id },
 { name: name, id: id } ] 
 }, 
 { name: "Cat3", elements : [ 
 { name: name, id: id },
 { name: name, id: id } ] 
 }
 ]
}

I would like to sort the array "category" based on the number of objects within the nested array "elements".

For example, after sorting, the above object might look like this (descending):

{
 category: [ 
 { name: "Cat2", elements : [ 
 { name: name, id: id },
 { name: name, id: id },
 { name: name, id: id } ] 
 }, 
 { name: "Cat3", elements : [ 
 { name: name, id: id },
 { name: name, id: id } ] 
 },
 { name: "Cat1", elements : [ 
 { name: name, id: id } ] 
 }
 ]
}

I am wondering if it is possible to accomplish this using javascript's sort() method. Any suggestions?

Thanks in advance!

asked Feb 20, 2010 at 10:34

2 Answers 2

19

The sort method accepts a function in which you can define how to compare two elements. Here's the relevant documentation.

compareFunction Specifies a function that defines the sort order. If omitted, the array is sorted lexicographically (in dictionary order) according to the string conversion of each element.

If compareFunction is supplied, the array elements are sorted according to the return value of the compare function. If a and b are two elements being compared, then:

  • If compareFunction(a, b) is less than 0, sort a to a lower index than b.

  • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.

  • If compareFunction(a, b) is greater than 0, sort b to a lower index than a.

Example code

var sorted_categories = original.category.sort(function (one, other) {
 //a - b is 
 // 0 when elements are the same
 // >0 when a > b
 // <0 when a < b
 return one.elements.length - other.elements.length;
});
vava
25.5k11 gold badges67 silver badges79 bronze badges
answered Feb 20, 2010 at 10:35
Sign up to request clarification or add additional context in comments.

3 Comments

It makes sense to cache the results of elements.length function as it will be called O(n * log n) times, i.e. a lot.
@Eli how can I make it Descending order.?
@Mrworldwide Switch one and other in the return statement like so return other.elements.length - one.elements.length;
-1
var category = [ 
 { name: "Cat1", elements : [ 
 { name: name, id: id } ] 
 },
 { name: "Cat2", elements : [ 
 { name: name, id: id },
 { name: name, id: id },
 { name: name, id: id } ] 
 }, 
 { name: "Cat3", elements : [ 
 { name: name, id: id },
 { name: name, id: id } ] 
 }
];
function myAbcSort(a, b){
 if(a.elements.length > b.elements.length) {
 return -1;
 } else {
 return 1;
 }
}
category.sort(myAbcSort);
answered Feb 20, 2010 at 10:42

1 Comment

Wrong. You must return 0 for the case a.elements.length == b.elements.length.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.