Array.prototype.sort Incorrect Numeric Sorting in JavaScript
JavaScript’s Array.prototype.sort() method is commonly used to sort arrays. However, when dealing with numbers, developers often encounter unexpected behavior. This issue occurs because JavaScript’s default sort method sorts values as strings rather than as numbers. This can lead to incorrect numeric sorting.
Understanding the Issue
Example of Incorrect Numeric Sorting
const numbers = [10, 5, 25, 1, 100];
console.log(numbers.sort());
Output:
[1, 10, 100, 25, 5]
Instead of sorting numerically ([1, 5, 10, 25, 100]), JavaScript sorts these numbers as strings, resulting in an order based on lexicographic (dictionary) sorting:
"1"(from1)"10"(from10)"100"(from100)"25"(from25)"5"(from5)
This happens because sort() converts elements to strings and sorts them based on Unicode code points.
Solution: Providing a Compare Function
To ensure correct numeric sorting, you need to provide a custom comparison function:
const numbers = [10, 5, 25, 1, 100];
numbers.sort((a, b) => a - b);
console.log(numbers);
Output:
[1, 5, 10, 25, 100]
Explanation of the Compare Function
How (a, b) => a - b Works
The sort() method takes a compare function (a, b), which:
- Returns negative (
a - b < 0) ifashould come beforeb - Returns positive (
a - b > 0) ifashould come afterb - Returns zero (
a - b == 0) if they are equal
| Comparison | Result | Sorting Order |
|---|---|---|
5 - 10 | -5 | 5 comes before 10 |
10 - 25 | -15 | 10 comes before 25 |
25 - 1 | 24 | 1 comes before 25 |
100 - 1 | 99 | 1 comes before 100 |
This forces JavaScript to sort numerically instead of lexicographically.
Descending Order Sorting
To sort numbers in descending order, simply reverse the subtraction:
const numbers = [10, 5, 25, 1, 100];
numbers.sort((a, b) => b - a);
console.log(numbers);
Output:
[100, 25, 10, 5, 1]
Handling Edge Cases
1. Sorting Floating Point Numbers
If your array contains floating-point numbers:
const numbers = [3.1, 2.5, 10.75, 0.9];
numbers.sort((a, b) => a - b);
console.log(numbers);
Output:
[0.9, 2.5, 3.1, 10.75]
2. Sorting Negative Numbers
The compare function works with negative numbers as well:
const numbers = [-10, 5, -2, 3, 0];
numbers.sort((a, b) => a - b);
console.log(numbers);
Output:
[-10, -2, 0, 3, 5]
3. Sorting Strings Containing Numbers
If your array contains numbers as strings:
const numbers = ["10", "5", "25", "1", "100"];
numbers.sort((a, b) => a - b);
console.log(numbers);
Output:
["1", "5", "10", "25", "100"]
Even though they are strings, JavaScript converts them into numbers implicitly.
4. Sorting an Array of Objects by Numeric Property
If sorting objects by a numeric key, use:
const users = [
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
{ name: "Charlie", age: 35 }
];
users.sort((a, b) => a.age - b.age);
console.log(users);
Output:
[
{ name: "Bob", age: 25 },
{ name: "Alice", age: 30 },
{ name: "Charlie", age: 35 }
]
