1

I've got an array of objects with names, like so:

myArray = [
           {name : 'foo'},
           {name : 'bar'},
           {name : 'Foo'}
          ]

I want to sort these object alphanumerically by name, and was using the following sort function to do so:

myArray.sort(function(a,b){
  return a.name > b.name;
});

This seems to work, but I can't find anything in the spec with regards to how sort is supposed to function when the comparison function returns booleans. This DOESN'T seem to follow the requirement that if a > b returns something greater than zero, a < b returns something less than zero, and a === b returns something equal to zero.

What I'm wondering is, will using a function that returns a boolean work consistently for sorting across browsers?

ckersch
  • 7,507
  • 2
  • 37
  • 44
  • One clever way to do it: http://stackoverflow.com/questions/17387435/javascript-sort-array-of-objects-by-a-boolean-property – Casey Falk Jul 18 '14 at 14:49
  • I can't provide evidence for all browsers but my assumption is that it casts whatever value back as a number and rounds it off (`true|0 == 1`) so it most likely works cross browser. – Mike Cluck Jul 18 '14 at 14:50

2 Answers2

2

Basically the function always returns 0 or 1, but never -1. I.e. If bar is compared against foo ('bar' > 'foo'), they are considered equal.

It may not work consistently across browsers because the actual sort algorithm is implementation dependent. And since your function never returns -1, the actual result may depend on the initial order of the elements.

So even though it looks like it works correctly, there are cases where it won't. You can't express three states (smaller, equal, larger) with a Boolean (true, false).

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 1
    I ended up using `myArray.sort(function(a,b){ return a.localeCompare(b) }` after running this on an array of 1000 strings, which the sort failed on. (Testing in chrome) – ckersch Jul 18 '14 at 15:11
0

It may work across all browsers (you would have to test them yourself), but if you're not following the spec, I wouldn't rely on this behavior. Still, because true == 1 and false == 0, one might assume that the browser's implementation isn't strictly checking the type of the return value, but only using it in a comparison.

Another thing you might not realize is that the sort is likely not doing what you think. Your comparator function is essentially saying that both names are the same even if a.name < b.name. This is the potentially dangerous part, as different sorting algorithms might use the result of the comparator in different ways, and depending on the underlying sort function used by the browser, the initial order of the elements in the array, and sometimes even the size and type of elements in the list (you'd be surprised), you may get unexpected, inaccurate results.

Just return a.name ? a.name.localeCompare(b.name) : -1; if you really want a one-liner.

Noyo
  • 4,874
  • 4
  • 39
  • 41