A directory of brand guidelines: logosearch.link

JavaScript sorts arrays weird

Dom Habersack
Dom HabersackJuly 15, 2020
Lines of candies.
When there’s no obvious way to sort them, just go by the alphabet.

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

A fire.
#42June 24, 2020

These tips are fire.

The bite-sized tips I started sharing on Twitter show how code can be improved gradually. You can read them all on this site now.

A bunch of balloons with either happy or sad faces drawn on them.
#78March 3, 2021

The end of annoying JavaScript imports

Instead of navigating many layers of directories when importing files, we can use aliases that cover that error-prone part for us.

A construction site warning sign telling people not to get closer.
#55September 23, 2020

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 all issues →