30

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 Answers3

74

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.

Chris Tavares
  • 29,165
  • 4
  • 46
  • 63
  • I figured as much, thanks. I just need to include what property to sort on, ie. return i.name.toLowerCase() or return i.description.toLowerCase() –  Sep 16 '14 at 17:01
  • This works great if you need to `_.uniq()` ignoring case too. – evolross Nov 21 '18 at 02:07
15

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.

Brad Vogel
  • 436
  • 3
  • 16
  • 3
    IE11 up https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare – Dan Eastwell Oct 09 '15 at 15:33
  • 1
    That works as well, but what is the reason not to use _sortBy for this? – JulienD Apr 21 '16 at 08:43
  • 1
    Because sortBy can't use `localCompare`, which is the correct way to compare strings. Instead, it uses the regular `<`, `>` operators for comparison. – Brad Vogel Apr 22 '16 at 01:10
  • 1
    @VincentWasteels this is no longer the case: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare – mustang Jun 18 '18 at 21:52
  • 1
    Kind of an incomplete example since the original requirement uses sortBy specifically to solve the problem of sorting arrays of objects, not strings, based on a specified property. – Greg Pettit Jan 31 '19 at 19:36
0

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());
Quoll42
  • 39
  • 4