Sort strings containing numbers
Sorting text is usually done using lexical ordering. But that handles numbers as characters.
This behavior results in a scenario when "item11" comes before "item9".
["item11", "item10", "item9"].sort() // ["item10", "item11", "item9"]
While this makes sense if you compare the strings character by character, as "1" comes before "9", it can hardly be considered user-friendly.
Use localeCompare
with the numeric
option
Apart from lexical sorting, Javascript supports comparison using locales, and that supports handling numbers in a more natural way.
Numeric-aware sorting is done by using localeCompare
, and passing {numeric: true}
to the options, the third argument.
To sort the above array using this method:
["item11", "item10", "item9"]
.sort((a, b) => a.localeCompare(b, undefined, {numeric: true}));
// ["item9","item10","item11"]
Use a Collator
If you need to sort in multiple places, it's better to specify the parameters of localeCompare
in one place instead of copy-pasting it. This is what Collator
is for. Create one instance with the parameters set, and use that when comparisons are needed.
Create a new instance, accepting the same parameters as localeCompare
, except for the string to compare with:
const collator = new Intl.Collator(undefined, {numeric: true});
It has a compare
property that is a valid compare function.
To sort the array using this collator:
["item11", "item10", "item9"].sort(collator.compare) // ["item9","item10","item11"]