Skip to content
Theory · Array methods · lesson 7 of 12

Sorting

The last worker at our conveyor is a sorter. The sorter takes two boxes, compares them and decides which one goes first. Pair by pair, the sorter puts the whole belt in order.

The sort method is such a sorter: it puts the elements of an array in order. With words it works as expected, but with numbers it does not:

JavaScript
const words = ["pear", "apple", "fig"];
words.sort();
console.log(words); // [ 'apple', 'fig', 'pear' ]

const nums = [25, 100, 3];
nums.sort();
console.log(nums); // [ 100, 25, 3 ]

Let's see what happened:

  1. The words are in alphabetical order: apple, fig, pear.
  2. The numbers are in a strange order: 100 comes first, although it is the largest.

Interviewers often ask why this happens with numbers. The answer lies in how sort compares elements without a hint.

Comparing as strings

Without an argument, sort converts each element to a string and compares the strings character by character, like words in a dictionary. The string "100" starts with "1", and "1" is less than "2" and "3". That is why 100 comes first, although as a number it is the largest.

The string "10" is also less than the string "9": "10" < "9" gives true. Strings are compared by character codes, so capital letters come before lowercase ones: ["b", "A", "a"].sort() gives [ 'A', 'a', 'b' ].

A compare function

To compare numbers as numbers, the sorter gets a rule. You pass a compare function to sort. sort calls it with two elements a and b and looks at the sign of the result:

  • a negative number — a goes before b;
  • a positive number — b goes before a;
  • 0 — the order of these two elements does not change.

The difference a - b is negative when a is smaller. So (a, b) => a - b sorts the numbers in ascending order, and (a, b) => b - a in descending order:

JavaScript
nums.sort((a, b) => a - b);
console.log(nums.join(" ")); // 3 25 100

nums.sort((a, b) => b - a);
console.log(nums.join(" ")); // 100 25 3

Take the pair 25 and 3 in an ascending sort. The difference 25 - 3 is 22, a positive number, so 3 goes before 25.

Anything can be compared, for example the length of strings: words.sort((a, b) => a.length - b.length).

A compare function must return a number: negative, positive or 0. The function (a, b) => a > b returns true or false. sort reads them as 1 and 0, and never gets a negative number. With it the order can come out wrong: in Node.js [3, 1, 2] stays [3, 1, 2].

sort and toSorted

Here the sorter analogy stops working. A real sorter could put the boxes onto a new belt, but sort does not create a new array. It rearranges the elements of the array it is called on.

sort changes the array

sort changes the array in place, like push and pop. sort returns that same array, not a copy.

toSorted returns a copy

The toSorted method takes the same compare function but returns a sorted copy and leaves the original array alone. The method was added to the language in 2023; Node.js 22 and browsers released after mid-2023 know it:

JavaScript
const scores = [70, 95, 80];
const ranked = scores.toSorted((a, b) => b - a);

console.log(ranked.join(" ")); // 95 80 70
console.log(scores.join(" ")); // 70 95 80

In ranked the scores are in descending order, and scores keeps the original order.

Common mistake

The result of sort is stored in a new constant, expecting the original array to stay as it was:

JavaScript
const prices = [30, 10, 20];
const sorted = prices.sort((a, b) => a - b); // ✗

console.log(prices.join(" "));

There is no error, but the program prints 10 20 30: sort rearranged the elements of prices itself. sorted and prices are two names for one array, and sorted === prices gives true. When the original order is needed later, write prices.toSorted((a, b) => a - b) or sort the copy [...prices].

Key points

  • Without an argument, sort compares elements as strings, so 100 comes before 25.
  • For numbers, pass a compare function: (a, b) => a - b for ascending, (a, b) => b - a for descending.
  • sort changes the array itself and returns it, while toSorted returns a new array.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way