JavaScript Arrays: Sort
Welcome to the Sort lesson!
JavaScript arrays' `.sort` puts the elements in order. However, there are important caveats to its use.
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
The
.sortmethod puts elements in order. We can use it to sort an array of strings alphabetically.>
const strings = ['c', 'a', 'b'];strings.sort();strings;Result:
['a', 'b', 'c']
.sortmodifies the array. We can see that in the example above: we sorted the array, then looked at it, and its content had changed. However,.sortalso returns the array to us.>
const strings = ['c', 'a', 'b'];strings.sort();Result:
['a', 'b', 'c']
Often, we want a sorted copy of an array without changing the original. We can use
.sliceto copy the array, then sort the copy.>
const originalStrings = ['c', 'a', 'b'];const sortedStrings = originalStrings.slice().sort();sortedStrings;Result:
['a', 'b', 'c']
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
originalStrings;Result:
['c', 'a', 'b']
JavaScript often converts values in surprising ways. For example,
10 > 3is true, but'10' < '3'is also true. This is because strings are compared character by character. The comparison ends as soon as two characters differ.'1' < '3', so'10' < '3'. The '0' in '10' is never even examined.>
'3' > '10';Result:
true
>
'200' > '3';Result:
false
.sortconverts the array's elements to strings, then compares them. Because it compares strings, it inherits the comparison problem above.This makes JavaScript's
.sortunsafe for numbers and most other data. Most other programming languages don't have this problem, so be careful!>
[3, 10].sort();Result:
>
[3, 10, 200].sort();Result:
[10, 200, 3]
There's a way to fix this problem. We can write our own comparison function, then give it to
.sort.The
.sortfunction will call our comparison function repeatedly. Each time, our function gets two array elements(a, b)as arguments and returns:- 0 if the two elements are equal.
- A number greater than zero if
ais greater. - A number smaller than zero if
bis greater.
To start,
.sortwill call our function with the values at indexes 1 and 0 in the array. Then it will continue to pass other pairs of array elements as it determines what the sorted order should be.Our comparison function only needs to determine which of two elements is greater, which is a relatively simple problem. By calling our comparison function over and over again,
.sorteventually solves the more difficult problem of sorting the entire array.>
[10, 200, 3].sort((a, b) => {if (a === b) {return 0;} else if (a > b) {return 1;} else {return -1;}});Result:
[3, 10, 200]
The above comparison function is very wordy. Fortunately, there's a shorthand that we can use. It relies on a trick:
- If
a === b, thena - b === 0. - If
a > b, thena - b > 0. - If
a < b, thena - b < 0.
- If
>
3 - 10 > 0;Result:
>
10 - 3 > 0;Result:
Now here's the trick: our callback function can return
a - b. According to the three cases outlined above,a - bwill correctly return a positive number, negative number, or 0, which is exactly what.sortwants.>
[10, 200, 3].sort((a, b) => a - b);Result:
[3, 10, 200]
We can use the comparison function for more than just numbers. For example, we can sort arrays by their lengths.
>
[[0, 0], [], [0, 0, 0], [0]].sort((a, b) => a.length - b.length);Result:
[[], [0], [0, 0], [0, 0, 0]]
We can even sort objects by a property.
>
const users = [{name: 'Amir', loginAttempts: 5},{name: 'Betty', loginAttempts: 3}];users.sort((user1, user2) => {return user1.loginAttempts - user2.loginAttempts;}).map(user => user.name);Result:
['Betty', 'Amir']