# Sorting Arrays

sort puts an array in order, but it compares items as text unless you give it a compare function, and it changes the array itself, so toSorted is the way to get a sorted copy and keep the original.

Apprentice · JavaScript · Updated November 1, 2026

## After this lesson you can

- Sort numbers and objects with a compare function, and explain why sort() alone puts 100 before 9
- Sort a copy with toSorted, leaving the original array in its order
- Choose map, filter, reduce, sort or a chain of them for a job

## Key takeaways

- sort with no compare function sorts items as text, so [10, 9, 100].sort() gives [10, 100, 9].
- A compare function gets two items, a and b, and returns a negative number to put a first or a positive number to put b first.
- (a, b) => a - b sorts numbers from lowest to highest, and (a, b) => b - a from highest to lowest.
- sort changes the array you call it on. toSorted gives back a sorted copy and leaves the original in its order.
- Pick the method by the job. map changes every item, filter keeps some, reduce boils them down to one value, sort or toSorted puts them in order.

"Price: low to high." "Newest first." "Top scores." Every shop, inbox and game puts lists in order, and the people using them expect it to be right: a leaderboard that puts 9 points above 100 points loses its players' trust fast. JavaScript arrays have a `sort` method, and it comes with one famous surprise. This lesson shows you the surprise, the fix, and how to sort without losing the order you started with.

The examples use the Comet Dash high-score list: gamer tags, scores, levels and the date each game was played.

## Putting things in order with sort

Think of putting a shelf of board games in alphabetical order. `sort` puts an array of words like these in order:

```javascript
const tags = ["NovaFox", "LunaByte", "PixelPanda", "CaptainCrumb"];

tags.sort();

console.log(tags);
```

```text
[ 'CaptainCrumb', 'LunaByte', 'NovaFox', 'PixelPanda' ]
```

(It compares character codes, so every capital letter comes before every small one: `['banana', 'Cherry'].sort()` puts *Cherry* first. `localeCompare`, below, sorts the way a person would.)

Notice that the line `tags.sort();` doesn't save a result anywhere, and `tags` is still sorted afterward. `sort` reorders the array **in place**: it changes the array you call it on. Keep that in mind; it comes back later in this lesson.

## The surprise: numbers sorted as text

Now try it with scores:

```javascript
const scores = [10, 9, 100];

scores.sort();

console.log(scores);
```

```text
[ 10, 100, 9 ]
```

That's not a typo. With nothing to go on, `sort` turns every item into text and puts the text in order character by character, as text. In a dictionary, every word starting with "1" comes before any word starting with "9", so `"10"` and `"100"` both land before `"9"`. It's the same reason a folder of files named `track1`, `track10` and `track9` can show up in that order.

## A compare function: which one goes first?

To sort numbers as numbers, you give `sort` a **compare function**: a callback that gets two items, `a` and `b`, and answers "which goes first?" with a number.

- A **negative** number means `a` goes first.
- A **positive** number means `b` goes first.
- **0** means they're tied, so they keep the order they had.

Subtracting gives exactly that kind of answer. `a - b` (read "a minus b") is negative when `a` is smaller, so the small numbers go first:

```javascript
const scores = [10, 9, 100];

scores.sort((a, b) => a - b);
console.log(scores);

scores.sort((a, b) => b - a);
console.log(scores);
```

```text
[ 9, 10, 100 ]
[ 100, 10, 9 ]
```

`(a, b) => a - b` sorts lowest to highest (in textbooks, **ascending**). `(a, b) => b - a` sorts highest to lowest (**descending**), which is what a leaderboard wants.

## Sorting records by score, by name or by date

A leaderboard sorts player objects, not plain numbers, so the compare function compares one property of each:

```javascript
const highScores = [
  { tag: "PixelPanda", score: 8200, date: "2026-10-03" },
  { tag: "NovaFox", score: 12450, date: "2026-10-05" },
  { tag: "LunaByte", score: 9900, date: "2026-10-07" },
];

highScores.sort((a, b) => b.score - a.score);
console.log(highScores.map((player) => player.tag));

highScores.sort((a, b) => a.tag.localeCompare(b.tag));
console.log(highScores.map((player) => player.tag));

highScores.sort((a, b) => b.date.localeCompare(a.date));
console.log(highScores.map((player) => player.date));
```

```text
[ 'NovaFox', 'LunaByte', 'PixelPanda' ]
[ 'LunaByte', 'NovaFox', 'PixelPanda' ]
[ '2026-10-07', '2026-10-05', '2026-10-03' ]
```

You can't subtract text, so for tags, `a.tag.localeCompare(b.tag)` does the comparing: it returns a negative number, a positive number or 0, exactly what sort needs, and it puts words in A-to-Z order the way a person would. Dates written year-month-day, like `"2026-10-07"`, sort correctly as text too, so `b.date.localeCompare(a.date)` puts the newest game first.

**Try it.** In a file named `sorting.js`, add CaptainCrumb (3100 points, played `"2026-10-05"`) to the list, and sort the players by score from lowest to highest. Run it with `node sorting.js`.

## sort changes the original; toSorted makes a copy

Because `sort` reorders the array itself, sorting a list for one screen changes it for every part of the program that uses it. Say the game shows players in the order they signed up, and the leaderboard sorts the same array:

```javascript
const signUps = [450, 8200, 3100];

const sorted = signUps.sort((a, b) => b - a);
console.log(signUps, sorted === signUps);

const signUpsAgain = [450, 8200, 3100];
const ranked = signUpsAgain.toSorted((a, b) => b - a);
console.log(signUpsAgain, ranked);
```

```text
[ 8200, 3100, 450 ] true
[ 450, 8200, 3100 ] [ 8200, 3100, 450 ]
```

`sorted === signUps` (read "strictly equal") is `true`: they're the same array, and the sign-up order is gone. `toSorted` takes the same compare function, but gives back a new, sorted array and leaves the original alone. Making a new value instead of changing the old one is called **immutability**, and it saves you from a whole family of "who changed my list?" bugs. `toSorted` arrived in JavaScript in 2023; every current browser and Node.js 20 or later have it. Older code makes the copy first, with spread: `[...signUps].sort((a, b) => b - a)`.

## Putting it together: a top-3 leaderboard

Now every piece of this chapter can work in one chain. `slice(0, 3)` copies the items from position 0 up to, but not including, position 3: the first three.

```javascript
const highScores = [
  { tag: "PixelPanda", score: 8200, level: 7 },
  { tag: "NovaFox", score: 12450, level: 9 },
  { tag: "CaptainCrumb", score: 3100, level: 3 },
  { tag: "LunaByte", score: 9900, level: 8 },
  { tag: "TurboSnail", score: 450, level: 1 },
];

const topThree = highScores
  .toSorted((a, b) => b.score - a.score)
  .slice(0, 3)
  .map((player, index) => `${index + 1}. ${player.tag}: ${player.score}`);

topThree.forEach((line) => console.log(line));
```

```text
1. NovaFox: 12450
2. LunaByte: 9900
3. PixelPanda: 8200
```

When you face a new list, ask what the job is, and the method follows:

| The job | The method | It gives back |
|---|---|---|
| Change every item (scores to display lines) | `map` | A new array, the same length |
| Keep only some items (players at level 5 or higher) | `filter` | A new array, the same length or shorter |
| Boil the list down to one answer (the total score) | `reduce` | One value |
| Put the items in order (highest score first) | `toSorted`, or `sort` to change the original | A sorted array |
| Several of these in a row (the top 3, as lines) | A chain, such as `toSorted`, then `slice`, then `map` | Whatever the last step gives |

## Check yourself

2 questions to try on the lesson page.

## So what

Putting a list in order sounds like the plainest job there is, and it's the one with the famous trap. Give sort a compare function, sort a copy with toSorted, and your leaderboards, price lists and inboxes come out the way people expect.

## Key terms

- [sort()](https://www.ask-codey.com/glossary/sort-javascript)
- Compare Function
- toSorted()
- [slice()](https://www.ask-codey.com/glossary/slice)
- [Immutability](https://www.ask-codey.com/glossary/immutability)

## Cheat sheets

- [Sorting Arrays](https://www.ask-codey.com/cheat-sheets/javascript-array-methods-sort-cheat-sheet)

## Related

- [map and filter](https://www.ask-codey.com/lessons/javascript-array-methods-map-and-filter)
- [reduce](https://www.ask-codey.com/lessons/javascript-array-methods-reduce)

Source: https://www.ask-codey.com/lessons/javascript-array-methods-sort
