How to sort an array of objects by several fields
Short answer
Compare by the first field, and if it is equal, by the second. The || operator moves on when the result is 0:
const users = [
{ name: 'Oleg', city: 'Paris' },
{ name: 'Anna', city: 'Rome' },
{ name: 'Maria', city: 'Paris' },
];
users.sort((a, b) => a.city.localeCompare(b.city) || a.name.localeCompare(b.name));
console.log(users.map((u) => `${u.city} ${u.name}`).join(', '));Output:
Paris Maria, Paris Oleg, Rome AnnaNumbers and descending order
For numbers, subtract. To reverse one field, swap a and b only for it:
const players = [
{ name: 'Anna', score: 90 },
{ name: 'Oleg', score: 75 },
{ name: 'Ivan', score: 90 },
];
players.sort((a, b) => b.score - a.score || a.name.localeCompare(b.name));
console.log(players.map((p) => `${p.name} ${p.score}`).join(', '));Output:
Anna 90, Ivan 90, Oleg 75Without changing the original
toSorted() returns a sorted copy:
const prices = [30, 10, 20];
const sorted = prices.toSorted((a, b) => a - b);
console.log(prices.join(), sorted.join());Output:
30,10,20 10,20,30Common mistake
sort() without a function compares values as strings, so 10 comes before 9:
console.log([9, 10, 1].sort().join(', '));Output:
1, 10, 9Functions used in this recipe
- Array.prototype.sort — Sorts the elements of an array.
- String.prototype.localeCompare — Compares strings by language rules — for alphabetical sorting.
- Array.prototype.toSorted — Returns a sorted copy of an array without changing the original.