5 useful tips about the JavaScript array sort method
Tags: javascript, beginners, codenewbie, 100daysofcode
Published: 2020-10-06 16:58:47

*If you like what I write, you may want to [subscribe to my newsletter](https://blog.greenroots.info/). Feel free to [@ me on twitter](https://twitter.com/tapasadhikary) for any discussion.*

<hr />
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. 

```js
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,

```shell
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.

```js
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,

```js
// 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,

```js
function (a,b) {
   return a === b ? 0 : a > b ? -1 : 1;
}
```
So now, let us sort the `artists` array in the descending order,

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

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

```shell
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,

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

ages.sort();
console.log(ages);
```
Output,

```shell
[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,

```js
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,

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

```shell
[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.

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

```shell
[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.

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

```shell
["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.

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

console.log(reversed);
```
Output,

```shell
["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.

```js
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,

```shell
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,

```js
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.

```js
 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](https://cdn.hashnode.com/res/hashnode/image/upload/v1601620226636/gSYeavKDZ.png?border=1,CCCCCC&auto=compress)

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.

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

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1601620431530/_K2KRS8Zy.png?border=1,CCCCCC&auto=compress)

## 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.

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

![outout_3.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1601623058235/ACxqwJ1G0.png?border=1,CCCCCC&auto=compress)

# 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.

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

```shell
["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,

```shell
"adam", "bakshi", "Bob", "carl", "Maya"
```
Use the compare function and compare the elements with the `toUpperCase()` to do a case insensitive comparison.

```js
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,

```shell
["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.

{% github atapas/js-array-sorting %}

You may also like,
- [Explain Me Like I am Five: What are ES6 Symbols?](https://blog.greenroots.info/explain-me-like-i-am-five-what-are-es6-symbols-ckeuz5sb8001qafs14of305dw)
- [Everything you need to know about JavaScript Set](https://blog.greenroots.info/everything-you-need-to-know-about-javascript-set-ckfgkprkg01pw8as1epsycua8)
- [How to use JavaScript Collection with Map](https://blog.greenroots.info/how-to-use-javascript-collection-with-map-ckfc477g005sy22s1fra3akvo)
- [10 lesser-known Web APIs you may want to use](https://blog.greenroots.info/10-lesser-known-web-apis-you-may-want-to-use-ckejv75cr012y70s158n85yhn)
- [Hey, I have made a demolab using JAMstack](https://blog.greenroots.info/hey-i-have-made-a-demolab-using-jamstack-ckeeiohqp0032f7s15c4c3ro6)

<hr />
If it was useful to you, please Like/Share so that, it reaches others as well.

You can @ me on Twitter ([@tapasadhikary](https://twitter.com/tapasadhikary)) with comments, or feel free to follow.