Question

Why does JavaScript sort not order numbers correctly?

Vault Verified
Curated Intelligence
Definitive Source
Answer

The default sort converts every element to a string and compares those strings. So ten sorts before nine, because the character one comes before nine. The array is correctly sorted, just alphabetically rather than numerically, which is rarely what anyone wants for numbers.

The fix is to pass a comparison function that returns a negative number, zero or a positive number depending on the desired order. For numbers, subtracting one from the other produces exactly that, which is why the idiomatic comparator looks so terse.

Two other properties of the method catch people out more often than the string comparison does.

It sorts in place and mutates the original array, as well as returning it. Assigning the result to a new variable does not protect the original, and a function that sorts an array it received as an argument has modified the caller data. Copying before sorting avoids this, and there is now a non-mutating variant available in modern runtimes.

Undefined values are always moved to the end regardless of the comparator, and the comparator is never called for them. This means a sparse array or one containing undefined behaves in a way the comparator cannot influence.

For strings, the default comparison is by character code, which handles plain lowercase text acceptably and mishandles anything else. Uppercase letters sort before all lowercase ones, and accented characters sort after the entire unaccented alphabet. Comparing with the locale-aware method produces the ordering a human would expect and handles case and accents correctly, at some performance cost on very large arrays.

Related Questions