The Basics of Sorting in JavaScript

Subscribe to my newsletter and never miss my upcoming articles

Sorting Defaults

By default, the sort() method in JavaScript will sort an array in place and works by looping through each item in the array and comparing each item two at a time until the array is sorted. To do this, it converts the array to strings and sorts them alphabetically in ascending order. This will only work well if there is a simple array of case-insensitive strings. For 99% of the time, you will need to write a custom compare function.

Compare Function

  • If a compare function is supplied, all non-undefined array elements are sorted according to the return value of the compare function (negative, zero, positive) value.
    • All undefined elements are sorted to the end of the array, with no call to the compare function.
  • If a and b are two elements being compared, then
    • If the result is negative a is sorted before b.
    • If the result is positive b is sorted before a.
  • If the result is 0 leave a and b unchanged with respect to each other but sorted with respect to all different elements.
  • It should be noted that you don't have to return -1 and 1 specifically. As long as one value is negative and one value is positive (greater than 0) it will still work. (However, you do need to specifically return 0 to represent equality between the items being compared.)
const compare = (a, b) => {  
   if (a < b) return -1;  
   if (a > b) return 1;  
   return 0; // a must be equal to b
}

Sort By Numbers

This is by far the simplest and most succinct of all the sorting method types so providing a code example should explain itself.

const sortByNumbersAsc = (a, b) => a - b //Ascending sort
const sortByNumbersDesc = (a, b) => b - a //Descending sort

Sort By Strings

Typically you will convert the strings you want to compare to a common case so use toLowerCase() or toUpperCase(). Whatever suits your fancy.

Good article on sorting Strings

//Ascending String sort
const sortByStringAsc = (a,b) => {  
   const aLower = a.toLowerCase();  
   const bLower = b.toLowerCase();  
   return aLower > bLower ? 1 : bLower > aLower ? -1 : 0;
}

//Descending String sort
const sortByStringDesc = (a,b) => {  
   const aLower = a.toLowerCase();  
   const bLower = b.toLowerCase();  
   return aLower > bLower ? -1 : bLower > aLower ? 1 : 0;
}

Sort Array of Objects

This is probably the most realistic way you will need to sort. Thankfully it’s not that much different from sorting a String or Number. Actually, it’s pretty much the same except instead of just the generic a & b comparison, you will need to explicitly state which object properties you want to compare against.

const cars = [  
{ make: "Nissan", year: 2017 },  
{ make: "Chevrolet", year: 2001 }, 
{ make: "BMW", year: 2010 }
];    

//Numeric sort - sort by year ascending
cars.sort((a,b) => a.year - b.year) 

//String sort - sort by car make πŸš—  ascending
const sortByStringAsc = (a,b) => {  
   const aMake = a.make.toLowerCase();  
   const bMake = b.make.toLowerCase();  
   return aMake > bMake ? 1 : bMake > aMake ? -1 : 0;
}

Descending Sort

I've provided examples of descending sorts in the respective code blocks but I wanted to write a little blurb about this as well.

If you need to sort in descending order, just swap the return 1 in the comparison function with return -1 for both a & b conditionals. Or put another way, it’s basically the reverse of the ascending sort logic.

Another way I’ve seen suggested to sort in descending order is to use the reverse() method.

Gotchas

Because the sort() method sorts an array in place, it will directly manipulate the array that is being sorted, therefore making it mutable πŸ‘ŽπŸ½. Due to this, you want to make sure you are working off of a copy of the array or using a package like immer to keep things immutable.

Resources

[Photo by UX Indonesia on Unsplash]

No Comments Yet