Sorting an Array in JavaScript
JavaScript's built-in sort()
function is often surprising to beginners. For example, suppose you sorted the below array:
[3, 20, 100].sort();
What would the output be? You might expect the array to stay the same, but the output will actually become:
[100, 20, 3];
That is because JavaScript converts array elements to strings and then sorts them according to JavaScript's ordering of strings.
Sorting an Array of Numbers
The sort()
function takes one parameter, compareFunction()
. The compareFunction()
function takes two array elements a
and b
. It should return:
- A negative number if
a < b
- A positive number if
a > b
- 0 if
a
is neither greater than nor less thanb
.
To sort an array of numbers in forward order, you should use (a, b) => a - b
as your compareFunction()
.
const arr = [3, 20, 100];
arr.sort((a, b) => a - b);
arr; // [3, 20, 100]
To sort an array of numbers in reverse order, you should use (a, b) => b - a
instead.
const arr = [20, 3, 100];
arr.sort((a, b) => b - a);
arr; // [100, 20, 3]
If you're familiar with Java, you can think of compareFunction()
as JavaScript's equivalent to compareTo()
.
Sorting an Array of Objects by Property
Suppose you instead wanted to sort an array of objects. For example, suppose you had an array of Star Trek: The Next Generation characters:
const characters = [
{ firstName: 'Jean-Luc', lastName: 'Picard', rank: 'Captain', age: 59 },
{ firstName: 'Will', lastName: 'Riker', rank: 'Commander', age: 29 },
{ firstName: 'Geordi', lastName: 'La Forge', rank: 'Lieutenant', age: 29 }
];
Here's how you would sort the characters
array by lastName
using JavaScript string comparison:
const characters = [
{ firstName: 'Jean-Luc', lastName: 'Picard', rank: 'Captain', age: 59 },
{ firstName: 'Will', lastName: 'Riker', rank: 'Commander', age: 29 },
{ firstName: 'Geordi', lastName: 'La Forge', rank: 'Lieutenant', age: 29 }
];
characters.sort((a, b) => {
if (a === b) {
return 0;
}
return a.lastName < b.lastName ? -1 : 1;
});
// La Forge, Picard, Riker
characters;
Here's how you would sort the characters
array by age:
const characters = [
{ firstName: 'Jean-Luc', lastName: 'Picard', rank: 'Captain', age: 59 },
{ firstName: 'Will', lastName: 'Riker', rank: 'Commander', age: 29 },
{ firstName: 'Geordi', lastName: 'La Forge', rank: 'Lieutenant', age: 29 }
];
characters.sort((a, b) => a.age - b.age);
// Riker, La Forge, Picard
characters;
How about sorting by rank
? Sorting by rank requires a custom ordering, because the JavaScript runtime doesn't know that 'Captain' is a higher rank than 'Lieutenant'. Here's how you would sort based on a custom ordering using indexOf()
.
const characters = [
{ firstName: 'Jean-Luc', lastName: 'Picard', rank: 'Captain', age: 59 },
{ firstName: 'Will', lastName: 'Riker', rank: 'Commander', age: 29 },
{ firstName: 'Geordi', lastName: 'La Forge', rank: 'Lieutenant', age: 29 }
];
const rankOrder = new Map([
['Captain', 1],
['Commander', 2],
['Lieutenant', 3]
]);
characters.sort((a, b) => {
return rankOrder.get(a.rank) - rankOrder.get(b.rank);
});
// Picard, Riker, La Forge
characters;