Sorting and Searching Arrays

Sort numbers, strings and objects correctly with compare functions, sort without changing the original, and search arrays with find, findIndex, includes, some and every.

Lesson 25 of 56Intermediate16 min read

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

JavaScript
array.sort((a, b) => a - b);

sort calls your function with two items, a and b, many times. Your function returns a number:

Return valueMeaning
Negativea comes before b
Positiveb comes before a
ZeroKeep 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

GoalCompare 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 originalReturns 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

MethodReturnsUse when you need…
includes(value)true / falseTo check if a simple value is present
indexOf(value)Index or -1The position of a simple value
find(fn)The first matching item or undefinedAn object that matches a condition
findIndex(fn)Its index or -1The position, for example to update it
findLast(fn) / findLastIndex(fn)The last matchThe 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 arrayEvery 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 - b sorts numbers ascending.
  • Use localeCompare for words, and chain comparisons with || for several fields.
  • sort changes the array; toSorted returns a sorted copy.
  • find, findIndex, includes, some and every search arrays and stop early.

JavaScript Sorting Arrays Examples

Each example runs in the page. Edit the code and press Run to see what changes.

Example 1

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 })));
ConsoleEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 3Without a compare function, numbers are compared as text: "100" before "25" before "9".
  2. Lines 4 to 5a - b and b - a sort numbers properly.
  3. Line 6toSorted leaves the original array as it was.
  4. Line 9Capitals sort before lower case, and "É" goes after "z".
  5. Line 10localeCompare sorts the way people expect.
  6. Line 13The numeric option sorts "file2" before "file10".
Example 2

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}`));
ConsoleEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 8Highest score first. Ali and Jo tie on 55 and keep their original order, because sort is stable.
  2. Lines 11 to 13Sort by team; when teams are equal (localeCompare returns 0), || falls through to the score.
Example 3

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);
ConsoleEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 7find returns the first matching object; ?. handles no match safely.
  2. Line 8findIndex gives its position.
  3. Line 9No match gives undefined.
  4. Lines 10 to 11some and every answer yes/no questions about the whole list.
  5. Line 14Sort a copy by price and take the first item.

Common JavaScript Sorting Arrays Mistakes

Sorting numbers without a compare function

Don't
[5, 25, 100].sort(); // [100, 25, 5]
Do
[5, 25, 100].sort((a, b) => a - b); // [5, 25, 100]

Returning a boolean from the compare function

Don't
items.sort((a, b) => a.price > b.price); // true/false isn't a valid order
Do
items.sort((a, b) => a.price - b.price);

Sorting shared data in place

Don't
const sorted = state.items.sort(byPrice); // also reorders state.items
Do
const 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.

Fill in the blankseasy

Sort the numbers from smallest to largest.

const nums = [30, 4, 15];
nums.sort((a, b) => a  b);
console.log(nums);
Predict the outputmedium

What is logged?

const a = [3, 1, 2];
const b = a.toSorted();
a.reverse();
console.log(a.join(""), b.join(""));
Multiple choiceeasy

Which method returns the first object that matches a condition?

Multiple choicemedium

Which compare function sorts names alphabetically, handling accents?

Fix the bugmedium

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);
ConsoleEdit the code, then press Run or Ctrl+Enter
Checks
  • Returns the top three, highest first
  • Original order is kept

JavaScript Sorting Arrays Quiz

5 questions to check what you learned.

  1. What does [2, 10, 1].sort() return?

    • [1, 2, 10]
    • [10, 2, 1]
    • An error
    • [1, 10, 2]
  2. What should a compare function return when a should come first?

    • A positive number
    • true
    • Zero
    • A negative number
  3. What does every() return for an empty array?

    • false
    • true
    • undefined
    • An error
  4. 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
  5. 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:

  1. sortBooks(books, field) returns a new array sorted by field: if field is "title" sort A to Z with localeCompare; if it's "year", sort oldest first
  2. findByAuthor(books, author) returns the first book whose author matches, ignoring case, or null if 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);
ConsoleEdit the code, then press Run or Ctrl+Enter
Checks
  • Sorts by title
  • Sorts by year
  • Doesn't change the original
  • Finds an author ignoring case