Palash Mondal
Code with Palash

Code with Palash

šŸ”„ Top 7 JavaScript Array sort() Method Use Cases

šŸ”„ Top 7 JavaScript Array sort() Method Use Cases

In this article, we will see the most common use cases for the Array sort() method and how we can utilise its power to the fullest. šŸš€

Palash Mondal's photo
Palash Mondal

Published on Aug 20, 2021

10 min read

Listen to this article

Hi Everyone šŸ‘‹

Today I wanted to share some of the most common use cases for Array sort() method in JavaScript. The sort() method sorts the elements of an array and returns the sorted array, and no copy is made. The default sort order is ascending. In this article, we will see how we can utilise its power to the fullest. šŸš€

Let's start!


Table of Contents


1. Sort an Array of Strings

Ascending (A to Z):

We can sort a simple array of strings using a functionless array sort() method like this:

let fruits = ['Apples', 'Watermelon', 'Bananas', 'Cherries'];
fruits.sort();    // šŸ‘ˆ default sort

console.log( fruits );
// ["Apples", "Bananas", "Cherries", "Watermelon"]
// A ā†’ B ā†’ C ā†’ W

Descending (Z to A):

To sort the array of strings in descending order we can use String localeCompare() method like this:

let fruits = ['Apples', 'Watermelon', 'Bananas', 'Cherries'];
fruits.sort((a, b) => b.localeCompare(a));

console.log( fruits );
// ["Watermelon", "Cherries", "Bananas", "Apples"]
// W ā†’ C ā†’ B ā†’ A

ā†‘ Back to top


2. Case-insensitive Sort an Array of Strings

Issue:

Let us first see what happens when we do a default sort for an array containing both lowercase and uppercase string elements.

let fruits = ['Apples', 'Watermelon', 'Bananas', 'cherries'];
fruits.sort(); 

console.log( fruits );
// ["Apples", "Bananas", "Watermelon", "cherries"]
// A ā†’ B ā†’ W ā†’ c

As you can see above output, with default sorting word Watermelon starting with a uppercase W is coming before cherries starting with a lowercase c. This happens because strings are sorted according to each character's Unicode code point value. Using string charCodeAt() we can get the UTF-16 code unit for each character and then see that:

'C'.charCodeAt()   // 67
'W'.charCodeAt()   // 87
'c'.charCodeAt()   // 99

// 67 < 87 < 99
// C ā†’ W ā†’ c

Ascending (aA to zZ):

Using case-insensitive sorting we can make sure that we get a properly sorted array, no matter what the casing for each string element in the array is:

let fruits = ['Apples', 'Watermelon', 'Bananas', 'cherries'];
fruits.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())); 

console.log( fruits );
// ["Apples", "Bananas", "cherries", "Watermelon"]
// A ā†’ B ā†’ c ā†’ W

Or,

let fruits = ['Apples', 'Watermelon', 'Bananas', 'cherries'];
fruits.sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' })); 

console.log( fruits );
// ["Apples", "Bananas", "cherries", "Watermelon"]

Descending (zZ to aA):

For case-insensitive sorting of array of strings in descending order we can simply interchange a & b element in the sorting compare function like this:

let fruits = ['Apples', 'Watermelon', 'Bananas', 'cherries'];
fruits.sort((a, b) => b.toLowerCase().localeCompare(a.toLowerCase())); 

console.log( fruits );
// ["Watermelon", "cherries", "Bananas", "Apples"]
// W ā†’ c ā†’ B ā†’ A

Or,

let fruits = ['Apples', 'Watermelon', 'Bananas', 'cherries'];
fruits.sort((a, b) => b.localeCompare(a, 'en', { sensitivity: 'base' })); 

console.log( fruits );
//  ["Apples", "Bananas", "cherries", "Watermelon"]

ā†‘ Back to top


3. Sort an Array of Numbers

Issue:

let numbers = [4, 2, 5, 1, 3, 10];
numbers.sort();    // šŸ‘ˆ default sort

console.log( numbers );
//  [1, 10, 2, 3, 4, 5]

In the above example, we can see that if we use a default sort on the numbers array we are getting an incorrect output as 10 is coming before 2 when it should be at the last position. This happens because array elements are sorted by converting them to strings and comparing strings in UTF-16 code units order. Thus in a numeric sort, 2 should come before 10, but because numbers are converted to strings, "10" comes before "2" in the Unicode order.

Ascending:

We can sort an array of numbers in ascending order using a simple compare function like this

let numbers = [4, 2, 5, 1, 3, 10];
numbers.sort((a, b) => a - b);   // šŸ‘ˆ compare function, simply return a - b

console.log( numbers );
// [1, 2, 3, 4, 5, 10]

Descending:

To sort an array of numbers in descending order we can simply interchange a & b elements in the sorting compare function like this:

let numbers = [4, 2, 5, 1, 3, 10];
numbers.sort((a, b) => b - a);   // šŸ‘ˆ interchange `a` & `b` and return b - a

console.log( numbers );
// [10, 5, 4, 3, 2, 1]

ā†‘ Back to top


4. Sort an Array of Date Strings

Issue:

// Date string in YYYY-MM-D format
let dates = [
  '2021-08-1',
  '2021-08-4',
  '2021-08-10',
  '2021-08-2'
];
dates.sort()    // šŸ‘ˆ default sort

console.log( dates )
// ["2021-08-1", "2021-08-10", "2021-08-2", "2021-08-4"]

In the above example, we can see that the date string "2021-08-10" is coming before "2021-08-2" which is not the expected output. It happens because of the same reason when sorting number array, where we found that 10 was coming before 2 when using default sorting.

Ascending:

To properly sort an array of date strings we can create a Date object by passing the date string to a new Date() inside the compare function like this:

let dates = [ '2021-08-1', '2021-08-4', '2021-08-10', '2021-08-2' ];
dates.sort((a, b) => new Date(a) - new Date(b))  // šŸ‘ˆ using `Date` constructor here

console.log( dates )
// ["2021-08-1", "2021-08-2", "2021-08-4", "2021-08-10"]

Descending:

For descending order we can simply interchange a & b elements in the sorting compare function like this:

let dates = [ '2021-08-1', '2021-08-4', '2021-08-10', '2021-08-2' ];
dates.sort((a, b) => new Date(b) - new Date(a))  // šŸ‘ˆ  here

console.log( dates )
// ["2021-08-10", "2021-08-4", "2021-08-2", "2021-08-1"]

ā†‘ Back to top


5. Sort an Array except for one Element

Let say we have a simple array like this

let fruits = ['Select', 'Apples', 'Watermelon', 'Bananas', 'Cherries'];

and we want to sort all elements in this array, except "Select". So, no matter if we are sorting the array in ascending/descending order we should always have "Select" at the first position. For this simple demo, we are assuming there are no duplicates in this array and each element starts with an uppercase and the rest of the letters are in lowercase. So we are not doing any case-insensitive sorting just to keep things simple.

Ascending:

We can do this in ascending order by adding a little bit of extra logic to the sort compare function like this:

let fruits = ['Select', 'Apples', 'Watermelon', 'Bananas', 'Cherries'];

fruits.sort((a, b) => {

  // If the first element value is "Select",
  // then keep it before second element. a < b
  if (a === 'Select') return -1;

  // If second element value is "Select",
  // then keep it before first element. a > b
  if (b === 'Select') return 1;

  // Else default sorting of string
  return a.localeCompare(b);
});

console.log( fruits )
// ["Select", "Apples", "Bananas", "Cherries", "Watermelon"]
// ā†‘ "Select" is at the first position and rest of the element is sorted

Descending:

For descending order logic we just need to interchange a & b for the localeCompare logic and we get the desired output.

let fruits = ['Select', 'Apples', 'Watermelon', 'Bananas', 'Cherries'];

fruits.sort((a, b) => {
  if (a === 'Select') return -1; 
  if (b === 'Select') return 1;

  return b.localeCompare(a);  // šŸ‘ˆ interchange `a` & `b` here
});

console.log( fruits )
// ["Select", "Watermelon", "Cherries", "Bananas", "Apples"]
// ā†‘ "Select" is still at the first position and rest of the element is sorted

ā†‘ Back to top


6. Sort Array of Objects by Property Value

Ascending:

We can sort an array of objects by a property value like this:

let inventory = [
  {name: 'Bananas', quantity: 5},
  {name: 'Apples',  quantity: 10},
  {name: 'Grapes',  quantity: 2}
];

// Sort by the "quantity" property value
inventory.sort((a, b) => a.quantity - b.quantity);  // šŸ‘ˆ here

console.log( inventory )
// Output
/*
[
  { "name": "Grapes",  "quantity": 2 },
  { "name": "Bananas", "quantity": 5 },
  { "name": "Apples",  "quantity": 10 }
]
*/

Now we can see that in the above array after sorting in ascending order, the object with name property value "Grapes" is coming first as its quantity value is lowest 2, then we have an object with quantity value 5 and then 10.

Descending:

For descending order logic we just need to interchange a & b in the sort compare function like:

let inventory = [
  {name: 'Bananas', quantity: 5},
  {name: 'Apples',  quantity: 10},
  {name: 'Grapes',  quantity: 2}
];

// Sort by the "quantity" property value
inventory.sort((a, b) => b.quantity - a.quantity);  // šŸ‘ˆ interchange `a` & `b` here

console.log( inventory )
// Output
/*
[
  { "name": "Apples",  "quantity": 10 },
  { "name": "Bananas", "quantity": 5 },
  { "name": "Grapes",  "quantity": 2 }
]
*/

ā†‘ Back to top


7. Sort Array of Objects by Multiple Property values

Ascending:

Let say we have an array like this:

let inventory = [
  {name:"Bananas", color:"Yellow", quantity:5},
  {name:"Apples", color:"Red", quantity:4},
  {name:"Apples", color:"Green", quantity:10},
  {name:"Grapes", color:"Green", quantity:2},
  {name:"Apples", color:"Yellow", quantity:6}
];

Our requirement is:

  1. First, we need to sort the name property values in ascending order.
  2. Then, we need to sort the quantity property values in ascending order.

So, we are looking for output like:

namequantitycolor
Apples4Red
Apples6Yellow
Apples10Green
Bananas5Yellow
Grapes2Green

So, you can see name column is sorted first alphabetically. Then for each having the same name value we sort them by quantity column.

Thus we have

// First
Apples ā†’ Bananas ā†’ Grapes 
A ā†’ B ā†’ G

// Then by quantity 
For Apples: 4 ā†’ 6 ā†’ 10
For Bananas: 5
For Grapes: 2

// Final output for quantity column
4 ā†’ 6 ā†’ 10 ā†’ 5 ā†’ 2

Though this logic seems super complex, but its solution is super easy:

let inventory = [
  {name:"Bananas", color:"Yellow", quantity:5},
  {name:"Apples", color:"Red", quantity:4},
  {name:"Apples", color:"Green", quantity:10},
  {name:"Grapes", color:"Green", quantity:2},
  {name:"Apples", color:"Yellow", quantity:6}
];

// Sort by the "name" property value, then by "quantity"
inventory.sort((a, b) => {
  let compareNames = a.name.localeCompare(b.name);
  let compareQuantity = a.quantity - b.quantity;

  // First compare using names
  // If values for "name" porperty for both a & b is same,
  // then compare by "quantity" property value
  return compareNames || compareQuantity;
})

// Output is the same as shown in the above table

Or, we can also write this in a one-line like:

inventory.sort((a, b) => a.name.localeCompare(b.name) || a.quantity - b.quantity);

and we still get the same output.

Descending:

Let say our requirement is now something like:

  1. First, we need to sort the name property values in ascending order.
  2. Then, we need to sort the quantity property values in descending order.

For this we just need to interchange a & b in the sort compare function for just quantity property only like:

// Sort by the "name" property value, then by "quantity" descending order
inventory.sort((a, b) => {
  let compareNames = a.name.localeCompare(b.name);
  let compareQuantity = b.quantity - a.quantity;  // šŸ‘ˆ interchange `a` & `b` here

  // First compare using names
  // If values for "name" porperty for both a & b is same,
  // then compare by "quantity" property value
  return compareNames || compareQuantity;
})

Or, just in one-line like:

inventory.sort((a, b) => a.name.localeCompare(b.name) || b.quantity - a.quantity);

And we get output like:

namequantitycolor
Apples10Green
Apples6Yellow
Apples4Red
Bananas5Yellow
Grapes2Green

ā†‘ Back to top


Wrap Up

I hope you will find this post useful and learn something new in the process. If you have any comments, additions or questions please let me know in the comment section.

Feedback, suggestions, and recommendations are highly welcome. This will really help me a lot and motivate me to share more content like this in future also. šŸ˜€

Happy Coding!

Did you find this article valuable?

Support Palash Mondal by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
Ā 
Share this