JavaScript's Default Array Sort
JavaScript's Array.sort
defaults to a String
sort. This catches many people off guard when attempting to sort an Array
of type Number
.
// ❌ Default search is a String search
const numbers = [10, 1, 3, 15]
numbers.sort() // [ 1, 10, 15, 3 ]
In the above example, each Number
is converted to a String
and then sorted using a String
sort.
At first, this can seem like a WTF JavaScript moment, but this happens because an Array
can contain mixed elements and JavaScript doesn't know how it should sort. So sort
defaults to a String
sort.
const array = [1, 2, 3, 'Joel', 4, { userId: 123 }]
When we want something other than a String
sort, we have to be explicit.
Custom Sort Compare Function
Creating a custom sort compare function is pretty easy. The function takes two elements, then we return -1
if the first is lower and 1
if it's higher. 0
for the same.
const compareFunction = (a, b) => {
// Pseudo Code
if (a is less than b) return -1
if (a is more than b) return 1
return 0
}
Then pass that function to the sort
method.
myArray.sort(compareFunction)
This flexibility will allow us to be creative with our sorting algorithms.
Number Sort
To sort a Number
Array
we could create a custom compareNumbers
function and pass that into Array.sort
.
const compareNumbers = (a, b) => a - b
const numbers = [10, 1, 3, 15]
numbers.sort(compareNumbers) // [ 1, 3, 10, 15 ]
Custom Object Sort
Let's say we had some data that looks like this:
const customers = [
{ id: 1, orders: ['a-1000', 'x-2000', 'c-8000'] },
{ id: 2, orders: ['a-1010'] },
{ id: 3, orders: ['a-1040', 'c-8050'] },
]
Our requirement is to sort by the number (length
) of orders
. So the order should be 2
, 3
, 1
.
We can do that with a custom compareOrderLength
function that will sort by customer.orders.length
.
const compareOrderLength = (a, b) => a.orders.length - b.orders.length
customers.sort(compareOrderLength)
/**
* [
* { id: 2, orders: [ 'a-1010' ] },
* { id: 3, orders: [ 'a-1040', 'c-8050' ] },
* { id: 1, orders: [ 'a-1000', 'x-2000', 'c-8000' ] }
* ]
*/
Complex Custom Sorting
I recently had a use case where an API was returning data that looked like this.
// API Response
["1", "10", "2", "BLA", "BLA2", "3"]
The Array
contained all String
items, but the business wanted the items to display like "1, 2, 3, 10, BLA, BLA2".
That meant, I had to detect when the String
was a Number
and Sort the "numbers" first and the text after.
As complex as that sounds, the sort algorithm wasn't too bad.
const isNumeric = (num) => !isNaN(num)
const customCompare = (a, b) => {
if (isNumeric(a) && !isNumeric(b)) return -1
if (!isNumeric(a) && isNumeric(b)) return 1
if (isNumeric(a) && isNumeric(b)) return a - b
return a < b ? -1 : 1
}
// [ '1', '2', '3', '10', 'BLA', 'BLA2' ]
End
So just remember the default Array
sort is a String
sort. To sort by anything else, you must create a compare function and pass that into sort.
- Check out my 📰 Newsletter
- Subscribe to my 📺 YouTube, JoelCodes
- Say hi to me on Twitter @joelnet
Cheers 🍻
Photo by Kelly Sikkema on Unsplash
Top comments (0)