The String localeCompare() method

By

Learn how the JavaScript localeCompare() method compares two strings by locale, returning a negative, zero or positive number, ideal for sorting text.

~~~

This method compares a string to another, returning a number (negative, 0, positive) that tells if the current string is lower, equal or greater than the string passed as argument, according to the locale.

The locale is determined by the current locale, or you can pass it as a second argument:

'a'.localeCompare('à') //-1
'a'.localeCompare('à', 'it-IT') //-1

Why not compare with < and >?

The comparison operators work on Unicode code unit values, not on alphabetical rules. That gives odd results as soon as you leave plain lowercase ASCII: every uppercase letter counts as “smaller” than every lowercase letter, and accented characters end up after z.

localeCompare() knows the actual sorting rules of human languages.

Sorting arrays

The most common use case is for ordering arrays:

['a', 'b', 'c', 'd'].sort((a, b) => a.localeCompare(b))

where one would typically use

['a', 'b', 'c', 'd'].sort((a, b) => (a > b) ? 1 : -1)

with the difference that localeCompare() allows us to make this compatible with alphabets used all over the globe.

Here’s the difference in practice:

['Cherry', 'banana', 'apple'].sort()
//[ 'Cherry', 'apple', 'banana' ]

['Cherry', 'banana', 'apple'].sort((a, b) => a.localeCompare(b))
//[ 'apple', 'banana', 'Cherry' ]

The default sort puts Cherry first because uppercase C has a lower code unit value than any lowercase letter. localeCompare() sorts the way a person would.

Passing options

An object passed as third argument can be used to pass additional options.

sensitivity: 'base' treats characters that differ only by accent or case as equal:

'a'.localeCompare('à', undefined, { sensitivity: 'base' }) //0

numeric: true compares sequences of digits as numbers, which is handy for file names or version strings:

const files = ['file10', 'file2']

files.sort((a, b) => a.localeCompare(b))
//[ 'file10', 'file2' ]

files.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))
//[ 'file2', 'file10' ]

Look for all the possible values of those options on MDN.

One thing to watch out for

Don’t test the result against exactly -1 or 1. The specification only guarantees the sign of the returned number, so an engine is free to return other negative or positive values.

Write if (city.localeCompare(otherCity) < 0) instead of if (city.localeCompare(otherCity) === -1). The first is always correct, the second can break.

~~~

Related posts about js: