TIL: behavior of JavaScript sort method

ยท 221 words ยท 2 minute read

I decided to solve this year’s Advent of Code using TypeScript with Deno because I want some stickers. At one point, I needed to sort an array. This is, very roughly, how my code looks like:

const array: Array<number> = [];
// Do something to the array
array.sort();

Found the problem? The problem is with the default comparator. I assumed that when a comparator is not provided, the less-than comparator is used. In other words, the array will be sorted in ascending order of the numerical values. That is not the case. Instead, if I print the array after sorting, this is how it looks like:

[ 18, 21, 26, 31, 35, 4 ]

Notice that it seems like they are sorted in lexicographical order. Indeed, according to the documentation:

If `compareFn`` is not supplied, all non-undefined array elements are sorted by converting them to strings and comparing strings in UTF-16 code units order. For example, “banana” comes before “cherry”. In a numeric sort, 9 comes before 80, but because numbers are converted to strings, “80” comes before “9” in the Unicode order.

The fix is simple, provide a comparator:

array.sort((a, b) => a - b);

Bonus: toSorted ๐Ÿ”—

I also learned from the IDE auto-completion that there is now a toSorted which sorts a copy of the array, instead of in-place.