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.
- All
- If
a
andb
are two elements being compared, then- If the result is negative
a
is sorted beforeb
. - If the result is positive
b
is sorted beforea
.
- If the result is negative
- If the result is 0 leave
a
andb
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]