How to use a custom comparison function in JavaScript
The default comparison function (lexicographical order)
The Array.prototype.sort()
method sorts the elements of an array and returns the sorted array. By default (without any arguments), it sorts in ascending order, by converting each element into a string, and comparing the UTF-16 code of each character. This is sometimes referred to as lexicographic ordering.
const months = ['January', 'February', 'March', 'April']
console.log(months.sort())
// [ 'April', 'February', 'January', 'March' ]
const numbers = [4, 2, 6, 10, 8, 13]
console.log(numbers.sort())
// [10, 13, 2, 4, 6, 8]
13
is sorted before 2
, 4
, 6
, and 8
, because its first character (1)
, has a smaller UTF-16 code than the others.
How to use a custom comparison function
The sort
method takes an optional comparison function that lets you sort elements using custom logic.
This function must return an integer where each integer determines how the two elements being compared are to be sorted.
compareFunction(a, b) return value | sort order |
---|---|
< 0 | sort a before b |
> 0 | sort a after b |
=== 0 | keep original order of a and b |
Here’s an example comparison function that sorts an array by placing the shortest words as the start (repl):
function sortByLengthAsc(a, b) {
if (a.length === b.length) {
// If the lengths are the same, keep original order.
return 0
}
if (a.length < b.length) {
// If a is shorter than b, put it before b.
// We want the shortest words to appear first.
return -1
}
// Put b after a
return 1
}
const sortedAscResult = ['Bob', 'Jimmy', 'Michelangelo', 'Mo'].sort(sortByLengthAsc)
console.log('Sorted by length (ASC):', sortedAscResult)
// Sorted by length (ASC): [ 'Mo', 'Bob', 'Jimmy', 'Michelangelo' ]
What about other values like null, undefined, false, etc?
undefined
elements are sorted to the end of the array:
[undefined, 'alice', 'bob', 'zarah'].sort()
// ['alice', 'bob', 'zarah', undefined]
Everything else is converted to a string (seemingly using the String()
constructor. For example:
// null values
[null, 'alice', 'bob', 'zarah'].sort()
// ['alice', 'bob', null, 'zarah']
// false values
[false, 'alice', 'bob', 'zarah'].sort()
['alice', 'bob', false, 'zarah']
// NaN values
['NaN', 'alice', 'NaM', 'bob', 'zarah'].sort()
// ['NaN', 'NaN', 'alice', 'bob', 'zarah'] // Capital letters are sorted before lowercase letters
In each case, you get the same result as if you passed the string equivalent (e.g., "null"
instead of null
or "false"
instead of false
).
Sources
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment