Sorting Numbers Correctly
Arrays have a sort method. Try it on some words and some numbers:
console.log(["pear", "fig", "apple"].sort());
console.log([10, 9, 1].sort());
Output:
[ 'apple', 'fig', 'pear' ]
[ 1, 10, 9 ]
The words come out in alphabetical order, but the numbers do not: 10 comes before 9. By default, sort turns every element into a string and compares the strings. As text, "10" comes before "9" because its first character, "1", comes before "9". It is the same reason "an" comes before "z" in a dictionary.
Text order has one more surprise. All capital letters come before all small letters:
console.log(["bob", "Carol", "alice"].sort());
Output:
[ 'Carol', 'alice', 'bob' ]
To sort numbers correctly, give the method a comparator. A comparator is a function that takes two elements, a and b, and returns a number:
- a negative number if
ashould come first - a positive number if
bshould come first - zero if their order does not matter
const nums = [31, 4, 15, 9, 26];
console.log(nums.toSorted((a, b) => a - b));
console.log(nums.toSorted((a, b) => b - a));
console.log(nums.toSorted());
console.log(nums);
Output:
[ 4, 9, 15, 26, 31 ]
[ 31, 26, 15, 9, 4 ]
[ 15, 26, 31, 4, 9 ]
[ 31, 4, 15, 9, 26 ]
a - b is negative when a is smaller, so smaller numbers come first. That is ascending order. b - a turns it around and gives descending order. You will use these two comparators often, so remember them. The third line has no comparator, so it compares as text again.
The example above uses toSorted, not sort. Both sort the same way. The difference is what happens to the original array:
const scores = [30, 10, 20];
const sorted = scores.toSorted((a, b) => a - b);
console.log(sorted);
console.log(scores);
scores.sort((a, b) => a - b);
console.log(scores);
Output:
[ 10, 20, 30 ]
[ 30, 10, 20 ]
[ 10, 20, 30 ]
toSorted returns a new sorted array and does not touch the original. sort changes the original array itself. Use toSorted unless you really want to change the array. In older code you will often see [...scores].sort(...). It copies the array with spread first and then sorts the copy, which does the same job as toSorted.
There is a similar pair for reversing. reverse() changes the array, and toReversed() returns a reversed copy.
Comparators work for any kind of data. In the Objects section you will use them to sort records, for example products by price.
In the exercise, sort one line of numbers three ways (default, ascending and descending), then print the original array.