# JavaScript Array Sort Method and its gotchas - Explained with Examples

In this article, we will see how to properly use the array sort method and learn common gotchas associated with it.

> Want to learn Redux in detail and build a complete food ordering app? check out my [Mastering Redux](https://master-redux.yogeshchavan.dev/) course. Following is the preview of the app, we'll be building in the course. It's a great project you can add to your portfolio/resume.

Note that, in this app, I have used INR as the currency for displaying the prices but you can easily change it to USD or AUD or any other currency with a single configuration change in the app.

%[https://www.youtube.com/watch?v=2zaPDfCKAvM]

----

### Let's get started

> The Array sort method sorts an array regardless of its data type - whether it's a numbered array, string array, or complex array of objects.

The sort method has the following syntax:

```js
array.sort([compareFunction])
```

Here, the `compareFunction` is optional.

**One thing you need to remember is that the Array sort method does not return a new sorted array, but instead changes the original array.**

```js
const months = ["Nov", "Feb", "Jan", "Dec" ];
const sorted = months.sort(); // sort the original array and return reference to it

console.log(months); // ["Dec", "Feb", "Jan", "Nov"]
console.log(sorted); // ["Dec", "Feb", "Jan", "Nov"]
```

Here's a [Code Pen Demo](https://codepen.io/myogeshchavan97/pen/yLyQbMJ?editors=0011).

If you compare the months and sorted variables using ===, you can see that they point to the same array which is the original sorted array.

*This is a very famous interview question to check if the candidate knows the array sort method.*

If you don’t want to change the original array, you can add a slice method before the sort method.

*The slice method returns a new shallow copy of an array.*

```js
const months = ["Nov", "Feb", "Jan", "Dec" ];
const sorted = months.slice().sort(); // returns a new sorted array

console.log(months); // ["Nov", "Feb", "Jan", "Dec"]
console.log(sorted); // ["Dec", "Feb", "Jan", "Nov"]
console.log(months === sorted); // false
```

Here's a [Code Pen Demo](https://codepen.io/myogeshchavan97/pen/zYxMwPE?editors=0011).

**By default, the sort method sorts an array as strings.**

This is fine in the case of strings that are sorted alphabetically, but it produces incorrect results when we sort numbers.

```js
const numbers = [100, 25, 1, 5 ];
const sorted = numbers.slice().sort(); // returns a new sorted array
console.log(numbers); // [100, 25, 1, 5 ]
console.log(sorted); // [1, 100, 25, 5]
```

Here's a [Code Pen Demo](https://codepen.io/myogeshchavan97/pen/MWYzmQp?editors=0011).

As you can see in the sorted array, 5 comes last and 100 comes before 25 even though 100 is larger than 25 and 5.

This is because when sorting numbers, each number is converted to a string. The sort method compares character by character, so the 1 in 100 is smaller than the 2 in 25 so while sorting in ascending order, 100 comes before 25.

This is a very common gotcha programmers usually forget.

We can fix it by passing the compare function to the sort method.

```js
const numbers = [100, 25, 1, 5];
const sorted = numbers.slice().sort(function(a, b) { 
 return a - b; 
}); // returns a new sorted array

console.log(numbers); // [100, 25, 1, 5]
console.log(sorted); // [1, 5, 25, 100]
```

Here's a [Code Pen Demo](https://codepen.io/myogeshchavan97/pen/MWYzmQp?editors=0011).

When comparing 100 and 25, the sort() method calculates 100 - 25 as 75 which is a positive value so it puts 25 before 100.

This will sort the array in ascending order.

To sort in descending order, we need to make a small change in the compare function.

```js
const numbers = [100, 25, 1, 5];
const sorted = numbers.slice().sort(function(a, b) { 
 return b - a; 
}); // returns a new sorted array

console.log(numbers); // [100, 25, 1, 5]
console.log(sorted); // [100, 25, 5, 1]
```

Here, we've used `b - a` instead of `a - b` to sort in descending order.
  
Here's a [Code Pen Demo](https://codepen.io/myogeshchavan97/pen/bGNQRdB?editors=0011).

So always pass the compare function when sorting numbers otherwise you will get an undesired result.

### Rules that sort function uses while sorting

1. If the first value is alphabetically before the second value, a negative value is returned.
2. If the first value is alphabetically after the second value, a positive value is returned.
3. If the first and second value is equal, zero is returned.

Now, let’s write a code that will sort the users by their last name.

```js
const users = ["David Jonhnson", "Tim Lindholm", "David Beckham", "Johnny Depp" ];
const sorted = users.slice().sort(function(firstUser, secondUser) { 
 const firstLastName = firstUser.split(" ")[1];
 const secondLastName = secondUser.split(" ")[1];
 
 if(firstLastName < secondLastName) return -1;
 if(firstLastName > secondLastName) return 1;
 return 0;
});

console.log(users); // ["David Jonhnson", "Tim Lindholm", "David Beckham", "Johnny Depp"]
console.log(sorted); // ["David Beckham", "Johnny Depp", "David Jonhnson", "Tim Lindholm"]
```

Here's a [Code Pen Demo](https://codepen.io/myogeshchavan97/pen/XWJyRoZ?editors=0011).

To sort an array in random order (shuffle), we can use the `Math.random` method

```js
const numbers = [100, 25, 1, 5 ];
const sorted = numbers.slice().sort(function(a, b) { 
 return 0.5 - Math.random() 
}); // returns a new sorted array

console.log(numbers); // [100, 25, 1, 5]
console.log(sorted); // array in random order
```

### Sorting an array of objects

Consider we have an array of user objects where each user object consists of a name and age property, and we want to sort the array based on the users' age in ascending order. We can do it as below:

```js
const users = [
    {
      name: 'David',
      age: 30
    },
    {
      name: 'Mike',
      age: 40
    },
    {
      name: 'John',
      age: 25
    }
];

const sorted = users.slice().sort(function(firstUser, secondUser) { 
 if(firstUser.age < secondUser.age) return -1;
 if(firstUser.age > secondUser.age) return 1;
 return 0;
});

console.log(users); // [{'name':'David','age':30},{'name':'Mike','age':40},{'name':'John','age':25}]
console.log(sorted); // [{'name':'John','age':25},{'name':'David','age':30},{'name':'Mike','age':40}]
```

Here's a [Code Pen Demo](https://codepen.io/myogeshchavan97/pen/bGNQRwg?editors=0011).

To sort the array in descending order of age:

```js
const users = [
    {
      name: 'David',
      age: 30
    },
    {
      name: 'Mike',
      age: 40
    },
    {
      name: 'John',
      age: 25
    }
];


const sorted = users.slice().sort(function(firstUser, secondUser) { 
 if(firstUser.age < secondUser.age) return 1;
 if(firstUser.age > secondUser.age) return -1;
 return 0;
});

console.log(users); // [{'name':'David','age':30},{'name':'Mike','age':40},{'name':'John','age':25}]
console.log(sorted); // [{'name':'Mike','age':40},{'name':'David','age':30},{'name':'John','age':25}]
```

Here's a [Code Pen Demo](https://codepen.io/myogeshchavan97/pen/bGNQrGv?editors=0011).

### Thanks for reading!

Want to learn all ES6+ features in detail including let and const, promises, various promise methods, array and object destructuring, arrow functions, async/await, import and export and a whole lot more from scratch?

Check out my [Mastering Modern JavaScript](https://modernjavascript.yogeshchavan.dev/) book. This book covers all the pre-requisites for learning React and helps you to become better at JavaScript and React.

**Check out free preview contents of the book [here](https://www.freecodecamp.org/news/learn-modern-javascript/).**

Also, you can check out my free [Introduction to React Router](https://yogeshchavan.podia.com/react-router-introduction) course to learn React Router from scratch.

Want to stay up to date with regular content regarding JavaScript, React, Node.js? [Follow me on LinkedIn](https://www.linkedin.com/in/yogesh-chavan97/).

[<img src="https://gist.github.com/myogeshchavan97/98ae4f4ead57fde8d47fcf7641220b72/raw/92ab4961521a20180285b6fdf5179b6d17fbcdff/freecodecamp_image.jpeg">](https://modernjavascript.yogeshchavan.dev/)

[<img src="https://cdn.buymeacoffee.com/buttons/default-yellow.png" >](https://www.buymeacoffee.com/myogeshchavan97)
