Skip to content

/commands/javascript/sort-array-of-objects-by-property

javascript sort array of objects by property

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · v24.20.0updated
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

bash
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.mjs

Output

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

GoalCompare 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.age returns true/false, which sort reads as 1/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.localeCompare throws 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 give NaN, 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