RemixNode's Blog

TwitterGitHub
5 useful tips about the JavaScript array sort method

5 useful tips about the JavaScript array sort method

JavaScript arrays are an ordered collection that can hold data of any type. Arrays are created with square brackets [...] and allow duplicate elements. In JavaScript, we can sort the elements of an array with the built-in method called, sort().

In this article, we will learn about the sort() method with 5 important tips(or information). Hope you find them useful.

1. The default array.sort() is for string type

The sort() method sorts the array elements and returns the sorted array.

let artists = [
    'John White Abbott', 
    'Leonardo da Vinci', 
    'Charles Aubry', 
    'Anna Atkins', 
    'Barent Avercamp'
];

let sorted = artists.sort();

console.log('Sort the artist names', sorted);

Output,

Sort the artist names
[
"Anna Atkins", 
"Barent Avercamp", 
"Charles Aubry", 
"John White Abbott", 
"Leonardo da Vinci"
]

Please note, the sort() method actually mutates the original array and both the original and sorted arrays are the same references.

console.log(artists === sorted); // returns true

Alright, an important point to note here is,

With the sort() method, the default sort order is ascending, and elements are converted into strings. Hence the default sort() method is not enough to sort arrays with different data type elements.

How about descending sorting order?

The default sort() method sorts in ascending order. How do we perform a sort in descending order? Welcome, compare function. A compare function helps elements to sort in an order according to its return value. Let us see it with an example,

// A compare function
function (a, b) {
    if (a > b) {
      return -1;
    }
    if (a < b) {
      return 1;
    }
    // a must be equal to b
    return 0;
 }

The above compare function helps to compare each of the elements in an array to perform a descending sort. Of course, the same function can be written in much simpler way as,

function (a,b) {
   return a === b ? 0 : a > b ? -1 : 1;
}

So now, let us sort the artists array in the descending order,

artists.sort(function (a, b) {
   return a === b ? 0 : a > b ? -1 : 1;
});

console.log('Sort the artist names(Descending)', artists);

Output,

Sort the artist names(Descending)
[
"Leonardo da Vinci", 
"John White Abbott", 
"Charles Aubry", 
"Barent Avercamp", 
"Anna Atkins"
]

How about sorting numbers?

The same philosophy applies. The default sort() function can not do it correctly. See this,

let ages = [2, 1000, 10, 3, 23, 12, 30, 21];

ages.sort();
console.log(ages);

Output,

[10, 1000, 12, 2, 21, 23, 3, 30]

Weird right? Yeah because with the default sort(), elements are converted to strings and compared in UTF-16 code units order. Hence the converted "12" comes before the converted "2".

We need a compare function for rescue here again. An ascending order sort can be done as,

ages.sort(function(a,b) {return a-b});
console.log(ages);

Note, the compare function passed to the sort() method. The compare function subtracts a from b and the result will be either of a positive number, negative number, or zero.

If you are using the ES6 coding style, you can write it using the arrow function as,

ages.sort((a,b) => a-b);

Output,

[2, 3, 10, 12, 21, 23, 30, 1000]

A descending number sort is an easy change, instead of the a-b, return b-a from the compare function.

ages.sort(function(a,b) {return b-a})
console.log(ages);

Output,

[1000, 30, 23, 21, 12, 10, 3, 2]

2. The array.reverse() is a force fit for sorting

The array.reverse() is another useful array method to order the elements in a reverse way.

let arr = ['bob', 'anna', 'elsa', 'marlon'];
console.log(arr.reverse());

Output,

["marlon", "elsa", "anna", "bob"]

As you see, the array elements are in reverse order now. This is good but, we often use the reverse() method for sorting.

let arr = ['bob', 'anna', 'elsa', 'marlon'];
let sorted = arr.sort(); // Ascending
let reversed = sorted.reverse(); // Descending

console.log(reversed);

Output,

["marlon", "elsa", "bob", "anna"]

It works but, may lead to an unexpected result as the reverse() is not meant for an order sorting, it is just for reversing. Please use the proper compare function for your sorting needs.

3. The non-ASCII character sorting is easy

In your application, you may encounter the strings which are non-English and represented by the non-ASCII characters. Use the string localeCompare() method in your compare function to sort them.

let items = ['communiqué', 'zèbre', 'adieu', 'éclair'];

items.sort();
console.log('Without localeCompare', items);

items.sort((a,b) => a.localeCompare(b));
console.log('With localeCompare', items);

Output,

Without localeCompare 
[
"adieu", 
"communiqué", 
"zèbre", 
"éclair"
]
With localeCompare 
[
"adieu", 
"communiqué", 
"éclair", 
"zèbre"
]

4. Sorting an object array == Sorting on value types

In JavaScript, objects are used to store multiple values as a complex data structure.

An object is created with curly braces {…} and a list of properties. A property is a key-value pair where the key must be a string and the value can be of any type.

Sorting an object is mostly about sorting based on property values. As the values can be of any type, let us understand various sorting with examples,

A user object,

let users = [
    {'name': 'Joe', 'address': 'Huston', 'dob':'February 9, 1991', 'income': 87654},
    {'name': 'Bob', 'address': 'London', 'dob':'July 1, 1986', 'income': 47974},
    {'name': 'Carl', 'address': 'Bangalore', 'dob':'December 25, 1982', 'income': 97351},
    {'name': 'Amanda', 'address': 'Lagos', 'dob':'March 19, 2001', 'income': 57753},
];

Sort by name

Use the compare function to compare the names of each object in the array.

 users.sort(function(a, b) {
    let left = a.name;
    let right = b.name;
    return left === right ? 0 : left > right ? 1 : -1;
  });

 console.table(users);

Output,

image.png

You know, what to do for a descending sort, right? Yeah, a bit of change in the compare function as shown earlier.

Sort by income

Income values are numbers. We know what to do here. We are going to compare the income values of the objects.

 users.sort((a,b) => (a.income - b.income));
 console.table(users);

Output,

image.png

Sort by date of birth(dob)

The user has a date of birth(dob property) which is a string. Well, we can not sort them like string, right? We need to sort them like dates. For a change, we are doing a descending order sort here means, the young person will be at the top.

users.sort((a,b) => (new Date(b.dob) - new Date(a.dob)));
console.table(users);

Output,

outout_3.png

5. You may need the case insensitive sorting

You may have to deal with array elements of different cases(capital and small). The default sort() function may not help. Here is an array with elements of mixed cases.

 let names = ['Bob', 'bakshi', 'adam', 'Maya', 'carl'];
 names.sort();
 console.log(names);

Output,

["Bob", "Maya", "adam", "bakshi", "carl"]

The above output is actually right as the comparison happens in the UTF-16 code units order. However, you may want it in the following order,

"adam", "bakshi", "Bob", "carl", "Maya"

Use the compare function and compare the elements with the toUpperCase() to do a case insensitive comparison.

names.sort(function (a, b) {
    let left = a.toUpperCase();
    let right = b.toUpperCase();

    return (left === right) ? 0 : left > right ? 1 : -1;
  });
console.log(names);

Output,

["adam", "bakshi", "Bob", "carl", "Maya"]

In Summary

The array sort() is easy to use. A comparison function is required in most of the cases.

In this article, we have discussed 5 key points,

  • The default array.sort() method sorts the array elements in the ascending order by converting them to strings.
  • Do not use array.reverse() for sorting. It may lead to unexpected results.
  • We can use the method localeCompare() to sort the non-ASCII characters.
  • Sorting an array of objects many need sorting on various data types.
  • Case insensitive sorting may be required in some cases.

Hope you find it useful. All the source code used in this article are here in my GitHub repo. Feel free to follow as I keep updating them with code examples.


If it was useful to you, please Like/Share so that, it reaches others as well. Please hit the Subscribe button at the top of the page to get an email notification on my latest posts.

You can @ me on Twitter (@tapasadhikary) with comments, or feel free to follow me.