JavaScript sorts arrays weird

Dom Habersack
Dom HabersackJuly 15, 2020

You don’t have to dig deep to find something strange in JavaScript. Any language created in 10 days would have quirks. While it has seen a lot of improvement in the last few years, some weirdness will always remain. One headscratcher is the default way it sorts arrays.

An array in JavaScript can hold all kinds of values. We can put whatever we want in them: numbers, strings, objects, other arrays, or anything else. We can also put all of them in the same array. Just because there are five numbers in an array does not prevent us from putting a string in there as well.

// this is totally fine
[15, true, 'Unobtanium', [2, 4], null, 81]

To sort arrays, we can use the built-in .sort() function. If we call it without any parameters, JavaScript applies a default sorting. It sorts an array of strings alphabetically:

['cucumber', 'apple', 'banana'].sort()
// ⇒ ['apple', 'banana', 'cucumber']

This is pretty straightforward so far. Check out how it sorts the numbers 1 through 10:

[3, 5, 6, 8, 10, 7, 2, 1, 9, 4].sort()
// ⇒ [1, 10, 2, 3, 4, 5, 6, 7, 8, 9]

It seems like JavaScript thinks 10 is larger than 1 but smaller than 2, which would be bonkers. What is going on here is something else. Because it does not try to understand what values those are, it treats ALL values as strings when sorting. Because alphabetically, the “1” in 10 comes before the “2” in 2, it puts 10 before 2. It does the same with other values (except undefined which always ends up last):

['trauma', null, 'why', true, undefined, false].sort()
// ⇒ [false, null, 'trauma', true, 'why', undefined]

The sorted version doesn’t seem any more or less sorted than the original version. JavaScript tries its best here by falling back to sorting alphabetically. It’s not obvious what order would make most sense in this last example.

We can help JavaScript out by providing a function to sort by. For numbers, we can do this in a single line:

[3, 5, 6, 8, 10, 7, 2, 1, 9, 4].sort((a, b) => a - b)
// ⇒ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

To sort numbers from largest to smallest, we swap a and b:

[3, 5, 6, 8, 10, 7, 2, 1, 9, 4].sort((a, b) => b - a)
// ⇒ [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

For most other cases, the correct sorting will depend on your data and the domain you work in. MDN has another few examples to check out:

Array.prototype.sort() on MDN

– Dom

Continue reading

September 23, 2020 (updated August 5, 2022)

The global .gitignore

Instead of ignoring the same files specific to your machine in every project, exclude them globally once for all your projects.

Read full article

Read all articles →