/commands/javascript/sort-array-of-objects-by-property
javascript sort array of objects by property
- tool
- JavaScript
- versions
- ES2019+ (stable sort), toSorted: ES2023, Node.js 20+
- os
- any
To sort an array of objects by a property, pass a compare function to sort(): users.sort((a, b) => a.age - b.age) for numbers, users.sort((a, b) => a.name.localeCompare(b.name)) for strings. The function returns a negative number when a goes first, a positive one when b goes first, and 0 to keep them in their current order.
Numbers, strings, descending, two keys
cat > sort.mjs <<'EOF'
const users = [
{ name: "Zoe", age: 31, team: "ops" },
{ name: "adam", age: 25, team: "dev" },
{ name: "Émile", age: 31, team: "dev" },
{ name: "Bea", age: 19, team: "ops" },
];
const names = (list) => list.map((u) => u.name).join(", ");
console.log("age asc: ", names(users.toSorted((a, b) => a.age - b.age)));
console.log("age desc: ", names(users.toSorted((a, b) => b.age - a.age)));
console.log("name <: ", names(users.toSorted((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))));
console.log("name locale:", names(users.toSorted((a, b) => a.name.localeCompare(b.name, "en"))));
console.log("team, then age:", names(users.toSorted((a, b) => a.team.localeCompare(b.team) || a.age - b.age)));
console.log("original untouched:", names(users));
EOF
node sort.mjsOutput
age asc: Bea, adam, Zoe, Émile age desc: Zoe, Émile, adam, Bea name <: Bea, Zoe, adam, Émile name locale: adam, Bea, Émile, Zoe team, then age: adam, Émile, Bea, Zoe original untouched: Zoe, adam, Émile, Bea
The plain < comparison sorts by code unit, so capital letters come before lowercase ones and accented letters go last. localeCompare sorts the way people read. The || trick chains keys: the second comparison only runs when the first returns 0.
Compare functions for common cases
| Goal | Compare function |
|---|---|
| Number ascending | (a, b) => a.price - b.price |
| Number descending | (a, b) => b.price - a.price |
| String, human order | (a, b) => a.name.localeCompare(b.name) |
| String, ignore case and accents | (a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: "base" }) |
| Numbers inside strings ("file10" after "file9") | (a, b) => a.file.localeCompare(b.file, undefined, { numeric: true }) |
| Dates | (a, b) => a.date - b.date (Date objects) or new Date(a.iso) - new Date(b.iso) |
| Booleans, true first | (a, b) => Number(b.active) - Number(a.active) |
Pitfalls
- In-place mutation.
sort()reorders the original array, which can break React state or code that relies on the old order.toSorted()returns a new array (Node.js 20+, current browsers); on older runtimes copy first with[...arr].sort(...). - Returning a boolean.
(a, b) => a.age > b.agereturnstrue/false, which sort reads as1/0; it never returns a negative number, so results differ between engines. Always return a number. - Missing properties. If some objects lack the key,
a.name.localeComparethrows Cannot read properties of undefined. Default it:(a.name ?? "").localeCompare(b.name ?? ""). - Subtracting strings such as
"10" - "9"works only because JavaScript converts them to numbers; non-numeric strings giveNaN, which leaves the order undefined.
Confirm it worked
Print the sorted key column, as the example does with map(u => u.name), and check the first and last values. For large arrays, arr.every((x, i) => i === 0 || cmp(arr[i - 1], x) <= 0) returns true when the array is in order.
FAQ
Why does [10, 9, 1].sort() return [1, 10, 9]?
Without a compare function, sort converts elements to strings and compares them in UTF-16 code unit order, so "10" comes before "9". Pass (a, b) => a - b for numbers.
Does sort() change the original array?
Yes, it sorts in place and returns the same array. Use toSorted() (ES2023, Node.js 20+) or [...arr].sort() when the original order must stay intact.
Is Array.prototype.sort stable?
Yes, since ES2019 the specification requires a stable sort: elements that compare equal keep their original relative order. That is what makes sorting by one key and then another reliable.
Sources
- developer.mozilla.orgdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
- developer.mozilla.orgdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted
- developer.mozilla.orgdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare