Array.prototype.sort incorrect numeric sorting*

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. "1" (from 1)
  2. "10" (from 10)
  3. "100" (from 100)
  4. "25" (from 25)
  5. "5" (from 5)

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) if a should come before b
  • Returns positive (a - b > 0) if a should come after b
  • Returns zero (a - b == 0) if they are equal
ComparisonResultSorting Order
5 - 10-55 comes before 10
10 - 25-1510 comes before 25
25 - 1241 comes before 25
100 - 1991 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 }
]

Leave a Reply

Your email address will not be published. Required fields are marked *