Lists are only useful if people can find things in them. Shops sort products by price, leaderboards rank players by score, contact lists go alphabetically, and search boxes look for the first matching item. JavaScript gives arrays a sort method and a family of search methods for all of this.
There's a famous trap waiting. Run [10, 9, 1, 100].sort() and you get [1, 10, 100, 9]. By default, sort compares items as text, so "100" comes before "9" just as "apple" comes before "banana". To sort numbers, dates or objects properly, you pass a compare function that tells sort how two items should be ordered.
In this lesson you'll learn how compare functions work, sort numbers, words in any language, and arrays of objects by one or more fields. You'll also learn the newer non-destructive methods toSorted and toReversed, and the search methods find, findIndex, findLast, includes, some and every, building on the array methods you already know.
How compare functions work
array.sort((a, b) => a - b);sort calls your function with two items, a and b, many times. Your function returns a number:
| Return value | Meaning |
|---|---|
| Negative | a comes before b |
| Positive | b comes before a |
| Zero | Keep their current order |
For numbers, a - b gives exactly this: ascending order. b - a sorts descending. Sorting is stable, meaning items that compare equal keep their original order, which matters when sorting by several fields one after another.
Sorting strings and objects
| Goal | Compare function |
|---|---|
| Numbers ascending | (a, b) => a - b |
| Numbers descending | (a, b) => b - a |
| Strings A to Z, any language | (a, b) => a.localeCompare(b) |
| Strings, ignoring case and accents | (a, b) => a.localeCompare(b, undefined, { sensitivity: "base" }) |
| Objects by a number | (a, b) => a.price - b.price |
| Objects by a string | (a, b) => a.name.localeCompare(b.name) |
| Dates | (a, b) => a.date - b.date |
| By two fields | (a, b) => a.team.localeCompare(b.team) || b.score - a.score |
localeCompare handles capitals and accented letters correctly, so "Émile" sorts near "Emma" instead of after "Zoe". Add { numeric: true } to sort "file2" before "file10".
sort changes the array: toSorted doesn't
sort and reverse change the original array and return it. That can cause bugs when other code still needs the original order. Modern JavaScript adds copies:
| Changes the original | Returns a new array |
|---|---|
arr.sort(fn) | arr.toSorted(fn) |
arr.reverse() | arr.toReversed() |
arr.splice(i, n) | arr.toSpliced(i, n) |
In older browsers, copy first: [...arr].sort(fn). Frameworks such as React rely on not mutating state, so the copying versions are the safe default.
Searching arrays
| Method | Returns | Use when you need… |
|---|---|---|
includes(value) | true / false | To check if a simple value is present |
indexOf(value) | Index or -1 | The position of a simple value |
find(fn) | The first matching item or undefined | An object that matches a condition |
findIndex(fn) | Its index or -1 | The position, for example to update it |
findLast(fn) / findLastIndex(fn) | The last match | The most recent item |
some(fn) | true if any item matches | "Is anything out of stock?" |
every(fn) | true if all items match | "Is every field filled in?" |
filter(fn) | All matches, as an array | Every matching item |
find, some and every stop as soon as they know the answer, so they're efficient on long lists.
JavaScript Sorting Arrays Syntax
Sorting and searching
nums.toSorted((a, b) => a - b);
names.toSorted((a, b) => a.localeCompare(b));
products.toSorted((a, b) => a.price - b.price);
players.toSorted((a, b) => b.score - a.score || a.name.localeCompare(b.name));
list.includes("x");
users.find(u => u.id === 7);
users.findIndex(u => u.id === 7);
items.some(i => i.stock === 0);
fields.every(f => f.value !== "");JavaScript Sorting Arrays Summary
sort()without a compare function sorts as text, so numbers come out wrong.- A compare function returns negative, positive or zero;
a - bsorts numbers ascending. - Use
localeComparefor words, and chain comparisons with||for several fields. sortchanges the array;toSortedreturns a sorted copy.find,findIndex,includes,someandeverysearch arrays and stop early.
JavaScript Sorting Arrays Examples
Each example runs in the page. Edit the code and press Run to see what changes.
The default sort trap
const scores = [10, 9, 1, 100, 25];
console.log("Default:", [...scores].sort());
console.log("Ascending:", scores.toSorted((a, b) => a - b));
console.log("Descending:", scores.toSorted((a, b) => b - a));
console.log("Original untouched:", scores);
const words = ["banana", "Apple", "cherry", "Émile"];
console.log("Default:", [...words].sort());
console.log("localeCompare:", words.toSorted((a, b) => a.localeCompare(b)));
const files = ["file10", "file2", "file1"];
console.log(files.toSorted((a, b) => a.localeCompare(b, undefined, { numeric: true })));Line-by-line explanation
- Line 3Without a compare function, numbers are compared as text: "100" before "25" before "9".
- Lines 4 to 5
a - bandb - asort numbers properly. - Line 6
toSortedleaves the original array as it was. - Line 9Capitals sort before lower case, and "É" goes after "z".
- Line 10
localeComparesorts the way people expect. - Line 13The numeric option sorts "file2" before "file10".
Sorting objects by one or more fields
const players = [
{ name: "Mia", team: "Red", score: 42 },
{ name: "Ali", team: "Blue", score: 55 },
{ name: "Jo", team: "Red", score: 55 },
{ name: "Kai", team: "Blue", score: 38 },
];
const byScore = players.toSorted((a, b) => b.score - a.score);
console.log(byScore.map(p => `${p.name} ${p.score}`));
const byTeamThenScore = players.toSorted(
(a, b) => a.team.localeCompare(b.team) || b.score - a.score
);
console.log(byTeamThenScore.map(p => `${p.team}: ${p.name} ${p.score}`));Line-by-line explanation
- Line 8Highest score first. Ali and Jo tie on 55 and keep their original order, because sort is stable.
- Lines 11 to 13Sort by team; when teams are equal (
localeComparereturns 0),||falls through to the score.
Searching a product list
const products = [
{ id: 1, name: "Mug", price: 8, stock: 12 },
{ id: 2, name: "Teapot", price: 24, stock: 0 },
{ id: 3, name: "Spoon", price: 3, stock: 40 },
];
console.log(products.find(p => p.id === 2)?.name);
console.log(products.findIndex(p => p.name === "Spoon"));
console.log(products.find(p => p.id === 99));
console.log("Any sold out?", products.some(p => p.stock === 0));
console.log("All under £30?", products.every(p => p.price < 30));
console.log(["mug", "spoon"].includes("spoon"));
const cheapest = products.toSorted((a, b) => a.price - b.price)[0];
console.log("Cheapest:", cheapest.name);Line-by-line explanation
- Line 7
findreturns the first matching object;?.handles no match safely. - Line 8
findIndexgives its position. - Line 9No match gives
undefined. - Lines 10 to 11
someandeveryanswer yes/no questions about the whole list. - Line 14Sort a copy by price and take the first item.
Common JavaScript Sorting Arrays Mistakes
Sorting numbers without a compare function
[5, 25, 100].sort(); // [100, 25, 5][5, 25, 100].sort((a, b) => a - b); // [5, 25, 100]Returning a boolean from the compare function
items.sort((a, b) => a.price > b.price); // true/false isn't a valid orderitems.sort((a, b) => a.price - b.price);Sorting shared data in place
const sorted = state.items.sort(byPrice); // also reorders state.itemsconst sorted = state.items.toSorted(byPrice);JavaScript Sorting Arrays in Real Projects
Sorting in real apps
Online shops sort by price, rating or newest with compare functions on product objects. Leaderboards sort by score then name. Email apps search with find for the selected message and some to show an "unread" badge. Data tables let users click a column header to sort, swapping between a - b and b - a for ascending and descending order.
JavaScript Sorting Arrays Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Sort the numbers from smallest to largest.
const nums = [30, 4, 15];
nums.sort((a, b) => a b);
console.log(nums);
a - b sorts numbers ascending.What is logged?
const a = [3, 1, 2];
const b = a.toSorted();
a.reverse();
console.log(a.join(""), b.join(""));Which method returns the first object that matches a condition?
Which compare function sorts names alphabetically, handling accents?
topThree(players) should return the names of the three highest scorers, highest first, without changing the original array. Fix it.
function topThree(players) {
return players.sort((a, b) => a.score > b.score).slice(0, 3).map(p => p.name);
}
const players = [
{ name: "A", score: 5 }, { name: "B", score: 50 }, { name: "C", score: 12 }, { name: "D", score: 30 },
];
console.log(topThree(players), players[0].name);- Returns the top three, highest first
- Original order is kept
JavaScript Sorting Arrays Quiz
5 questions to check what you learned.
What does [2, 10, 1].sort() return?
- [1, 2, 10]
- [10, 2, 1]
- An error
- [1, 10, 2]
What should a compare function return when a should come first?
- A positive number
- true
- Zero
- A negative number
What does every() return for an empty array?
- false
- true
- undefined
- An error
What's the difference between sort and toSorted?
- toSorted is slower
- toSorted only works on numbers
- sort changes the original array; toSorted returns a new sorted array
- There's none
In (a, b) => a.team.localeCompare(b.team) || b.score - a.score, when is the score used?
- Only when the teams are equal, because localeCompare returns 0
- Always
- Never
- Only for the first item
JavaScript Sorting Arrays Challenge
Sort and search a book list
Write two functions:
sortBooks(books, field)returns a new array sorted byfield: iffieldis"title"sort A to Z withlocaleCompare; if it's"year", sort oldest firstfindByAuthor(books, author)returns the first book whoseauthormatches, ignoring case, ornullif there's none
function sortBooks(books, field) {
}
function findByAuthor(books, author) {
}
const books = [
{ title: "Wolf Hall", author: "Hilary Mantel", year: 2009 },
{ title: "Beloved", author: "Toni Morrison", year: 1987 },
{ title: "Atonement", author: "Ian McEwan", year: 2001 },
];
console.log(sortBooks(books, "title").map(b => b.title), findByAuthor(books, "toni morrison")?.title);- Sorts by title
- Sorts by year
- Doesn't change the original
- Finds an author ignoring case