Numerical array sorting in JavaScript
26 August 2008 · Estimated reading time: 2 minutes
In these troubled times, it can be hard to know whom to trust. In looking for a numerical sort function, the first two articles I found both recommended the same syntax. Both of them were wrong.
Now, maybe I shouldn't be casting stones, considering my last blog post. The truth is, the technique those sites offered will work in most cases, but technically leaves scripts open to errors at the edges.
In JavaScript, you can sort an array just by calling its native sort
method. By default, this sorts the contents as strings. That's all fine and dandy when what you're sorting are, in fact, strings, but not when you're sorting numbers (e.g., 10 would come before 9).
The remedy for this is to pass a comparison function to the sort
method. The comparison function needs to return -1 if the first argument should come before the second argument, 0 if they are equivalent in sort order, and 1 if the first argument should come after the second.
In most cases, the following syntax (suggested by both of the above linked sites) would work:
var myArray = [10, 9]; myArray.sort(function (a, b) { return a - b; }); // myArray is now [9, 10]
It's terse. It's simple. Looks good, right? Wrong.
The Mozilla Developer Center (an authoritative source, I reckon) has this to say about the above technique:
To compare numbers instead of strings, you should not subtract the numbers because this can cause overflow. For example,
9e307-(-9e307)
equalsNumber.POSITIVE_INFINITY
but so does9e307-(-9.9e307)
.
The solution is to be more explicit in the comparisons. Here's the syntax I've settled on for this:
var myArray = [10, 9]; myArray.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; }); // myArray is now [9, 10]
The moral of the story: check multiple sources, watch for non-obvious gotchas, and never, ever take candy from strangers.