Sorting Arrays in JavaScript

Like many other popular languages, JavaScript conveniently comes with a built-in method for sorting arrays. While the end result is the same, the various JavaScript engines implement this method using different sort algorithms:

  • V8: Quicksort or Insertion Sort (for smaller arrays)
  • Firefox: Merge sort
  • Safari: Quicksort, Merge Sort, or Selection Sort (depending on the type of array)

The implementation doesn't really matter for the calling code, but it's interesting to see these sorting algorithms used in practice after learning about them for so long in CS intro classes.

This sort function is available as a prototype method on the Array class:

Array.sort([compareFunc])

In true JavaScript fashion, a callback is passed to this function which is used to tell the sorting algorithm how two elements compare to each other. The compareFunc should have two parameters, a and b, and works like this:

  • If compareFunc returns 0 then the elements are treated as equal
  • If compareFunc returns 1 then b is sorted before a
  • If compareFunc returns -1 then a is sorted before b

The function doesn't necessarily need to return 1 or -1, just as long as the numbers returned are 0, above 0, or below 0. So a comparator function like (a, b) => a - b; is perfectly valid.

If the compareFunc is not given then the elements are converted to strings and then sorted alphabetically. This makes sorting strings trivial. However, while sorting numbers seems like it should be straight forward, it can actually be a bit confusing here:

> let nums = [3, 2, 6, 50, 10];
> nums.sort()
[ 10, 2, 3, 50, 6 ]

As you can see, the numbers aren't in the order you would have expected. This is because, as mentioned earlier, that the default sorting method is to convert the elements to strings before doing the comparison. And as a string, "50" comes before "6", which is why 50 isn't last in the array. To sort this array correctly, try the following instead:

> let nums = [3, 2, 6, 50, 10];
> nums.sort((a, b) => a - b);
[ 2, 3, 6, 10, 50 ]

Note: It's important to keep in mind that this method sorts in-place, which means that the original array is actually sorted and no copy is made. So, while the .sort() method does return the sorted array, you don't actually need to assign it to anything since the array that it is called on is sorted.

If you want to reverse the order of the sorting, just switch around the comparison of a and b. So if we want the numbers to be in descending order, you'd do the following:

> let nums = [3, 2, 6, 50, 10];
> nums.sort((a, b) => b - a);
[ 50, 10, 6, 3, 2 ]

Sorting Array of Objects

Using a comparator function like this makes it extremely easy to sort custom objects in JavaScript. For example, let's say we have the following list of user data:

let users = [
    {name: 'Scotty', age: '18'},
    {name: 'Tommy', age: '21'},
    {name: 'Sally', age: '71'},
    {name: 'Billy', age: '18'},
    {name: 'Timmy', age: '21'}
];

This isn't something that the sorting algorithm can just interpret and sort itself. The order also highly depends on the application. What if we want to sort by age and then name? To do so, we could provide a comparator that combines the two:

users.sort((a, b) => {
    let keyA = a.age + a.name;
    let keyB = b.age + b.name;
    if (keyA < keyB) return -1;
    if (keyA > keyB) return 1;
    return 0;
});

This will result in the following sorted array:

[ { name: 'Billy', age: '18' },
  { name: 'Scotty', age: '18' },
  { name: 'Timmy', age: '21' },
  { name: 'Tommy', age: '21' },
  { name: 'Sally', age: '71' } ]

Notice that all of the users are now sorted by age. And as intended, those users with the same age are then sorted by name, like Billy and Scotty.

Conclusion

In this short article we saw how to use the built-in .sort() method to easily sort arrays in JavaScript. This applies to any type of data, including strings, numbers, or even objects. The sort order is determined by the compareFun callback method, which is what allows you to determine the sort order or what object properties determine the sort order.