JavaScript Sort In A Nutshell
Jun 24, 2021
sort-comparer-javascript,
sort-comparer,
sort,
javascript-array.sort,
array.sort,
array.prototype.sort,
1023 Views
JavaScript Array sort demystified for you and explains to you its default behavior and shows examples on how to use the comparer functions.
JavaScript Sort In A Nutshell
Introduction
As a developer, you might encounter sorting many times in your career.
There are many ways you can sort types of collections in any given programming language using different algorithms. However, in this article, we're going to explore the JavaScript [].sort function, and we'll see how we can utilize this function.
Today, most developers use utility libraries like Lodash to help them in their productivity in their day-to-day job. However, learning the built-in [].sort function in the JavaScript language won't hurt. But instead, I believe it will help us gain a deeper understanding of the JavaScript language.
OK, let's get started.
How Array.prototype.sort() Works?
The JavaScript language provides a sort() method that sorts the array items into ascending order (smallest value first and largest value last).
Syntax
Array.sort([comparer])
The comparer argument is an optional argument which is a function that compares two elements of the array.
The JavaScript [].sort function is quite weird, so you might not expect the exact results you expect once you have tried this method individually.
Let's try to see one example.
const myNums = [100,1001,20,1,56,989];
console.log(myNums.sort());
//output: [1, 100, 1001, 20, 56, 989]
On the example above, we have an array of numbers, and then we have invoked the sort function, and as you can see, the result is quite different from what we expect.
Makes no sense? Yes, it makes perfect sense.
Here's what's happening it converts each item in the array into strings. It then constructs the sequence by comparing each item based on UTF 16 code values when there is no callback specified.
We're going to tackle the callback a bit later, but as of now, let's see the next section about UTF-16.
What is UTF-16?
UTF-16 stands for 16-bit Unicode Transformation Format. It's a form of translating bits into a format known to humans.
Just like the ASCII, UTF-16 has its own table of translations for a given character. Moreover, according to Wikipedia, JavaScript uses UTF-16 as its encoding.
Therefore, because JavaScript uses UTF-16 internally, and when we invoke the sort function.
We are essentially sorting against the UTF-16 character table. Therefore it is done based on character appearance rather than mathematical reasoning or rules.
I hope you got the message, guys! And hopefully, you won't be scratching your head now 😉.
The Comparer Callback Function
Using the default sort function wouldn't be so helpful, in my opinion. However, and thankfully, this function takes an optional callback (the comparer function).
This comparer function makes the items in the array sorted based on the returned value.
In general, this callback function takes two arguments, A and B. And use these arguments to create an expression that either returns 1,-1, or 0.
Let's see how we can create a compare function to sort the array elements.
function compare(a, b) {
if (a > b) return 1;
if (b > a) return -1;
return 0;
}
Here are things to remember with the code sample above.
If the function returns:
- less than zero, A comes before B.
- greater than zero, B comes before A.
- to zero, A and B positions are left unchanged.
If you think that the compare function, which is the example in this section, can be refactored into a simpler code, you're right.
Let's see how we can do that; see the example below.
function compare(a, b) {
return a - b;
}
JavaScript Sorting Arrays of Number, Strings, Dates, and Objects.
Sort Arrays of Numbers
If you have read the previous section, this would be easy for you to understand.
Let's jump ahead to see an example.
const myNums = [100, 1001, 20, 1, 56, 989];
const compareAsc = (a, b) => (a - b);
const compareDesc = (a, b) => (b - a);
console.log(myNums.sort(compareAsc));
//output: [ 1, 20, 56, 100, 989, 1001 ]
console.log(myNums.sort(compareDesc));
//output: [ 1001, 989, 100, 56, 20, 1 ]
Sort Arrays of Strings
When dealing with strings, we can use JavaScript's localCompare method. It is highly recommended because it gives you much more options.
Furthermore, it has built-in support for things like language-specific sort ordering, ignoring cases, or diacritics.
const names = ['Jin', 'Vincent', 'Necesario'];
const compareAsc = (a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' });
const compareDesc = (a, b) => b.localeCompare(a, 'en', { sensitivity: 'base' });
console.log(names.sort(compareAsc));
//output: [ 'Jin', 'Necesario', 'Vincent' ]
console.log(names.sort(compareDesc));
//output: [ 'Vincent', 'Necesario', 'Jin' ]
Sort Arrays of Dates
Comparing or sorting dates is easy. If you have seen how we can sort the numbers, we can then easily apply these to type Dates.
Let's jump ahead to see an example.
const _dates = [new Date(1990, 3, 5), new Date(2000, 3, 5), new Date(1980, 11, 10)];
const compareAsc = (a, b) => a - b;
const compareDesc = (a, b) => b - a;
console.log(_dates.sort(compareAsc).map((item) => item.toDateString()));
//output: [ 'Wed Dec 10 1980', 'Thu Apr 05 1990', 'Wed Apr 05 2000' ]
console.log(_dates.sort(compareDesc).map((item) => item.toDateString()));
//output: [ 'Wed Apr 05 2000', 'Thu Apr 05 1990', 'Wed Dec 10 1980' ]
Sort Arrays of Objects
When comparing the properties of an object, we just have to combine the existing knowledge we have from the previous examples. Therefore, we can develop a solution on how we can sort these objects by their properties.
Let's see an example below.
const basketBallPlayers = [
{
name: "Lebron James",
jersey: 23,
birthDate: new Date(1984, 12, 30)
},
{
name: "Kobe Bryant",
jersey: 24,
birthDate: new Date(1978, 8, 23)
},
{
name: "Michael Jordan",
jersey: 23,
birthDate: new Date(1963, 2, 17)
},
{
name: "Jason Kidd",
jersey: 5,
birthDate: new Date(1973, 3, 23)
}
];
function compareValues(key, order = 'asc') {
return (a, b) => {
if (typeof a[key] === "number" && typeof b[key] === "number") {
return order === 'asc' ? a[key] - b[key] : b[key] - a[key];
}
else if (typeof a[key] === "object" && typeof b[key] === "object") {
if (a[key] instanceof Date && b[key] instanceof Date) {
return order === 'asc' ? a[key] - b[key] : b[key] - a[key];
}
}
else if (typeof a[key] === "string" && typeof b[key] === "string") {
return order === 'asc' ? a[key].localeCompare(b[key], 'en', { sensitivity: 'base'}): b[key].localeCompare(a[key], 'en', { sensitivity: 'base'}) ;
}
};
}
console.log(basketBallPlayers.sort(compareValues('birthDate', 'desc')));
/*
output:
[
{
name: 'Lebron James',
jersey: 23,
birthDate: 1985-01-29T16:00:00.000Z
},
{
name: 'Kobe Bryant',
jersey: 24,
birthDate: 1978-09-22T16:00:00.000Z
},
{
name: 'Jason Kidd',
jersey: 5,
birthDate: 1973-04-22T16:00:00.000Z
},
{
name: 'Michael Jordan',
jersey: 23,
birthDate: 1963-03-16T16:00:00.000Z
}
]
*/
console.log(basketBallPlayers.sort(compareValues('name')));
/*
output:
[
{
name: 'Jason Kidd',
jersey: 5,
birthDate: 1973-04-22T16:00:00.000Z
},
{
name: 'Kobe Bryant',
jersey: 24,
birthDate: 1978-09-22T16:00:00.000Z
},
{
name: 'Lebron James',
jersey: 23,
birthDate: 1985-01-29T16:00:00.000Z
},
{
name: 'Michael Jordan',
jersey: 23,
birthDate: 1963-03-16T16:00:00.000Z
}
]
*/
console.log(basketBallPlayers.sort(compareValues('jersey')));
/**
* output:
* [
{
name: 'Jason Kidd',
jersey: 5,
birthDate: 1973-04-22T16:00:00.000Z
},
{
name: 'Lebron James',
jersey: 23,
birthDate: 1985-01-29T16:00:00.000Z
},
{
name: 'Michael Jordan',
jersey: 23,
birthDate: 1963-03-16T16:00:00.000Z
},
{
name: 'Kobe Bryant',
jersey: 24,
birthDate: 1978-09-22T16:00:00.000Z
}
]
*/
Summary
Great! You have made it this far.
This article has seen how we can use the JavaScript [].sort method to sort arrays of numbers, string, dates, and objects.
Once again, I hope you have enjoyed this article/tutorial as I have enjoyed writing it. This article was originally written and posted here.
Stay tuned for more. Until next time, happy programming!
Please don't forget to bookmark, like, and comment. Cheers! And Thank you!