Sort an Array of Objects in JavaScript
Suppose you have a JavaScript array containing 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 }
];
How do you sort this array by different properties?
Sorting By age
JavaScript's built-in Array#sort()
function optionally
takes a callback parameter that
compares two elements in the array.
The callback function is called compareFunction()
. If compareFunction(a, b)
returns a value that is < 0
, JavaScript considers a
to be less than b
.
And if compareFunction(a, b)
returns a value that is > 0
, JavaScript considers b
to be greater than a
.
That means it is easy to sort by a numeric property like age
. If a.age - b.age < 0
, that means b
is older than a
.
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;
Sorting by lastName
Sorting by a string property like lastName
is also easy, because
JavaScript's <
and >
properties can handle strings. To sort
by a string property, your compareFunction()
can compare the
two strings using <
:
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;
Sorting by rank
Sorting by rank
is a bit trickier because rank isn't necessarily
in alphabetical order. JavaScript doesn't know that 'Captain' is
a higher rank than 'Lieutenant'.
To sort by a custom ordering, you should define a map from
rank
to a numeric value to make for easier 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 }
];
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;