23

I've got an array of objects, each of which has a property name, a string. I'd like to sort the array by this property. I'd like them sorted in the following way..

`ABC`
`abc`
`BAC`
`bac`
etc...

How would I achieve this in JavaScript?

2
  • Isn't this array.sort() ? It does exactly what you want. Commented Mar 24, 2011 at 15:13
  • 1
    @Raynos: No it doesn't. You need to compare the name property of each object, which sort() will not do without a custom function. Commented Mar 24, 2011 at 15:26

5 Answers 5

52

There are 2 basic ways:

var arr = [{name:"ABC"},{name:"BAC"},{name:"abc"},{name:"bac"}];

arr.sort(function(a,b){
  var alc = a.name.toLowerCase(), blc = b.name.toLowerCase();
  return alc > blc ? 1 : alc < blc ? -1 : 0;
 });

or

arr.sort(function(a,b){
  return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
 });

Be aware that the 2nd version ignore diacritics, so a and à will be sorted as the same letter.

Now the problem with both these ways is that they will not sort uppercase ABC before lowercase abc, since it will treat them as the same.

To fix that, you will have to do it like this:

arr.sort(function(a,b){
  var alc = a.name.toLowerCase(), blc = b.name.toLowerCase();
  return alc > blc ? 1 : alc < blc ? -1 : a.name > b.name ? 1 : a.name < b.name ? -1 : 0;
});

Again here you could choose to use localeCompare instead if you don't want diacritics to affect the sorting like this:

arr.sort(function(a,b){
  var lccomp = a.name.toLowerCase().localeCompare(b.name.toLowerCase());
  return lccomp ? lccomp : a.name > b.name ? 1 : a.name < b.name ? -1 : 0;
});

You can read more about sort here: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort

Sign up to request clarification or add additional context in comments.

1 Comment

Doesn't work for Romanian diacritics... :-(
3

You can pass-in a sort function reference to Array.sort.

1 Comment

Together with the accepted answer, this helped me solve the issue. I think it should be a part of the accepted answer.
1
objects.sort(function(c, d) {
    return (
        c['name'].toLowerCase() > d['name'].toLowerCase() || 
            c['name'] > d['name']
    ) ? 1 : -1;
});

see there http://jsfiddle.net/p8Gny/1/

2 Comments

This is not the right way to use the sort funciton which needs a return range of 1,0,-1 and not true,false like yours return. Read the docs here: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
@Martin Jespersen Thank you for correcting me.
1

You can pass a custom sorting function to the sort() method of an array. The following will do the trick and take your requirements about capitalization into account.

objects.sort(function(o1, o2) {
    var n1 = o1.name, n2 = o2.name, ni1 = n1.toLowerCase(), ni2 = n2.toLowerCase();
    return ni1 === ni2 ? (n1 === n2 ? 0 : n1 > n2 ? 1 : -1) : (ni1 > ni2 ? 1 : -1);
});

3 Comments

isn't that the same as array.sort() I think you just passed in the default sorting function directly.
@Raynos: No, my function compares the name property of two objects. I have updated it now to account for the order the OP wanted regarding capitalization.
I completely overlooked that you have to compare names not object references. Such a simple mistake.
1

Slightly modified from Sorting an array of objects,

yourobject.sort(function(a, b) {
    var nameA = a.name, nameB = b.name
    if (nameA < nameB) //Sort string ascending.
        return -1
    if (nameA > nameB)
        return 1
    return 0 //Default return value (no sorting).
})

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.