30
votes

Having some slight issues trying to get underscore.js to do case-insensitive sorting. I have an array of objects and would like to be able to sort by property name.

Using shortcut method sortBy

iteratee may also be the string name of the property to sort by (eg. length).

Array to be sorted:

var array = [{ name: 'test_1234', description: 'zzaaa bb cc'}, 
         { name: 'zz1111', description: 'ZAAbbbcc'}, 
         { name: 'TEST', description: '4422'}, 
         { name: '1a2929', description: 'abcdef'}, 
         { name: 'abc', description: 'Full description'}, 
         { name: 'GGGGH', description: '123456'}];

Sorting using this method, sortProperty = 'name', the result places uppercase before lowercase.

var sorted = _.sortBy(array, sortProperty);

1a2929 - abcdef
GGGGH - 123456
TEST - 4422
abc - Full description
test_1234 - zzaaa bb cc
zz1111 - ZAAbbbcc

I assume this has to do with case sensitivity, but I can't figure out how to change names in the array to lowercase and compare that way.

Any help is greatly appreciated.

Edit: As pointed out, you pass in name or a function, so just adjusted function to return which field to sort by: http://jsfiddle.net/rjaqp1vg/5/

3

3 Answers

73
votes

The name to sort by can be the field name OR a function, so pass a function that does a lower-case conversion.

var sorted = _.sortBy(array, function (i) { return i.name.toLowerCase(); });

should do the trick.

15
votes

Don't use _.sortBy for this. The correct way to sort strings alphabetically is to use localeCompare. Here's an example in pure Javascript:

['Z', 'A','z','รก', 'V'].sort(function(a, b){
   return a.localeCompare(b, undefined /* Ignore language */, { sensitivity: 'base' }) 
});

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare.

0
votes

Chris' answer worked well for me, and I made it a little shorter with an arrow function:

var sorted = _.sortBy(array, (i) => i.name.toLowerCase());