The better way to do natural sort in JavaScript
One thing about JavaScript that I wouldn’t put in The Good Parts is how it handles array sorting.
The default sort order is built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values. - MDN
What does that do?
1 | const months = ['March', 'Jan', 'Feb', 'Dec'] |
Nice. How about this?
1 | const array1 = [1, 30, 4, 21, 100000] |
Well…that’s not what I wanted. If you know you’re getting an array of numbers ahead of time, you can make a sort function accordingly.
1 | const numbers = [4, 2, 5, 1, 3] |
OK, not bad. We can sort strings and numbers differently. Unless your array has numbers or strings containing numbers in it.
1 | const uhoh = ['3rd', 'Apple', '24th', '99 in the shade', 'Dec', '10000', '101'] |
The traditional way around this problem was to create a natural sort function of such profound and startling ugliness I advise the faint of heart to look away.
1 | function naturalSort (a, b) { |
I warned you. Good luck with your therapist.
I needed a natural sort on a new project, and before I copied Big Ugly, I stumbled across this thing of beauty.
1 | const items = ['3rd', 'Apple', '24th', '99 in the shade', 'Dec', '10000', '101', '$1.23'] |
Now we’re talking.
The localeCompare() method returns a number indicating whether a reference string comes before or after or is the same as the given string in sort order. - MDN
The localeCompare()
string method has arguments for the locale, which sets the sort algorithm (here I get the locale from the browser), and additional options, which I use to turn on numeric collation and ignore punctuation. You can read all about the options here.
50 incomprehensible lines of JavaScript down to one. I think we can stick Array sorting in The Good Parts now. Works in IE11 too.