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?

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
Skizit
  • 43,506
  • 91
  • 209
  • 269
  • Isn't this `array.sort()` ? It does exactly what you want. – Raynos Mar 24 '11 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. – Tim Down Mar 24 '11 at 15:26

5 Answers5

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

Martin Jespersen
  • 25,743
  • 8
  • 56
  • 68
3

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

JRL
  • 76,767
  • 18
  • 98
  • 146
  • Together with the accepted answer, this helped me solve the issue. I think it should be a part of the accepted answer. – ezuk Dec 14 '11 at 11:17
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);
});
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • isn't that the same as `array.sort()` I think you just passed in the default sorting function directly. – Raynos Mar 24 '11 at 15:14
  • @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. – Tim Down Mar 24 '11 at 15:18
  • I completely overlooked that you have to compare names not object references. Such a simple mistake. – Raynos Mar 24 '11 at 15:37
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).
})
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Aleadam
  • 40,203
  • 9
  • 86
  • 108
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/

avrelian
  • 798
  • 6
  • 10
  • 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: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort – Martin Jespersen Mar 24 '11 at 15:26
  • @Martin Jespersen Thank you for correcting me. – avrelian Mar 24 '11 at 15:34