Skip to content
On this page

Sort

Sorting algorithms are frequently used in programming. Whether you use bubble sort or quick sort, the core of sorting involves comparing two elements. For numbers, we can compare them directly, but what about strings or objects? In such cases, comparing them mathematically makes no sense, so the comparison process must be abstracted through a function. Typically, for two elements ( x ) and ( y ), if you consider ( x < y ), you return -1; if ( x == y ), you return 0; and if ( x > y ), you return 1. This way, sorting algorithms do not need to concern themselves with the specific comparison process but can sort based on the comparison results.

JavaScript's Array.prototype.sort() method is used for sorting, but the results might surprise you:

javascript
// Looks normal:
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft']

// 'apple' is last:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft', 'apple']

// Unintelligible result:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]

In the second sort, 'apple' is last because strings are sorted based on their ASCII values, and the ASCII code for lowercase 'a' comes after uppercase letters.

The third result is confusing: why does it mis-sort simple numbers? This happens because Array.prototype.sort() converts all elements to strings for comparison. Consequently, '10' comes before '2' since the character '1' has a smaller ASCII value than '2'.

Custom Sorting

If you are unaware of sort()'s default sorting rules, sorting numbers directly can lead to unexpected outcomes!

Fortunately, sort() is a higher-order function that also accepts a comparison function for custom sorting.

To sort numbers correctly, you can write:

javascript
let arr = [10, 20, 1, 2];

arr.sort(function (x, y) {
    if (x < y) {
        return -1;
    }
    if (x > y) {
        return 1;
    }
    return 0;
});

console.log(arr); // [1, 2, 10, 20]

For descending order, you can place larger numbers first:

javascript
let arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
    return y - x;
}); // [20, 10, 2, 1]

The comparison function passed to sort() accepts two parameters, ( x ) and ( y ). If ( x < y ), it should return a negative number; if ( x > y ), return a positive number; if ( x = y ), return 0.

By default, string sorting compares based on ASCII values. Now, let’s implement a sorting algorithm that ignores case and sorts alphabetically. We can achieve this without major changes to existing code, as long as we define a case-insensitive comparison:

javascript
let arr = ['Google', 'apple', 'Microsoft'];
arr.sort(function (s1, s2) {
    let x1 = s1.toUpperCase();
    let x2 = s2.toUpperCase();
    if (x1 < x2) {
        return -1;
    }
    if (x1 > x2) {
        return 1;
    }
    return 0;
}); // ['apple', 'Google', 'Microsoft']

Comparing two strings case-insensitively essentially means converting both strings to uppercase (or lowercase) before comparison.

As shown in the examples, higher-order functions offer powerful abstraction capabilities while keeping core code clean and simple.

Important Note

The sort() method modifies the Array in place and returns the same Array:

javascript
let a1 = ['B', 'A', 'C'];
let a2 = a1.sort();
a1; // ['A', 'B', 'C']
a2; // ['A', 'B', 'C']
a1 === a2; // true, a1 and a2 are the same object
Sort has loaded