How to Sort Array Elements in JavaScript?

How to Sort Array Elements in JavaScript?

Sorting array elements using the sort method

Sorting is any process of arranging items systematically in a sequence ordered by some criterion so that you can analyze it more effectively. In this article, I want to describe a common method used to sort array elements in alphabetical and numerical order. In addition to general examples, I have provided a real-life use-case example to clarify the context of sorting array values.

Let's dive in and have fun!

Introduction

Sorting is the process of arranging data into meaningful order so that you can analyze it more effectively. For example, you might want to sort the data in a column to find the string "Alex" or you might want to order sales data by calendar month so that you can produce a graph of sales performance.

Sorts are most commonly in numerical or a form of alphabetical (called lexicographical) order and can be in ascending (A-Z, 0-9) or descending (Z-A, 9-0) order.

Why sorting data is important?

Sorting is an important algorithm in Computer Science because it can often minimize the complexity of a task or simply to facilitate the later search for members of the sorted set. These algorithms have direct applications in search algorithms, database algorithms, divide-and-conquer methods, data structure algorithms, and a variety of other areas.

Note: There are different sorting algorithms for different cases but they are not in the context of this article.

I think it's enough for the theory so let's dive into the practical part!

Sorting Array Elements Alphabetically

The very straightforward and easy way to sort array elements alphabetically is to use the Array.prototype.sort method.

Ascending Sort

The sort method sorts the elements of an array in place and returns the sorted array. The default sort order is ascending.

The sort method needs an optional compareFunction(firstEl, secondEl) parameter that defines the sort order. If omitted, the array elements are converted to strings, then sorted according to each character's Unicode code point value.

Let's look at the example below:

const names = ['Williams', 'James', 'Alex', 'Mason', 'Ella', 'Jackson'];

// Sort the "names" array
names.sort();

console.log(names);
// Output: ["Alex", "Ella", "Jackson", "James", "Mason", "Williams"]

Descending Sort

You can just as easily sort the elements of an array in ascending order, but if you want to sort the elements in descending order, use the Array.prototype.reverse method after the array has been sorted as the example below:

const names = ['Williams', 'James', 'Alex', 'Mason', 'Ella', 'Jackson'];

// Sort the "names" array
names.sort();

// Reverse the "names" array
names.reverse();

console.log(names);
// Output: ["Williams", "Mason", "James", "Jackson", "Ella", "Alex"]

The reverse method reverses an array in place. The first array element becomes the last, and the last array element becomes the first.

Warning: Be careful, the sort method is destructive. It changes the original array. If you want to overcome this problem, make a shallow copy of the array at first and then invoke the sort method as in the example below:

const names = ['Williams', 'James', 'Alex', 'Mason', 'Ella', 'Jackson'];

// Make a shallow copy of the "names" array
const copyOfNames = [...names];

// Sort the "copyOfNames" array
copyOfNames.sort();

console.log(names);
// Output: ["Williams", "James", "Alex", "Mason", "Ella", "Jackson"]

console.log(copyOfNames);
// Output: ["Alex", "Ella", "Jackson", "James", "Mason", "Williams"]

Sorting strings with non-ASCII characters

For sorting strings with accented characters (e, é, è, a, ä, etc.) and strings from languages other than English, use the localeCompare method within the compareFunction parameter of sort method.

The localeCompare method can compare those characters so they appear in the right order.

Let's look at this cool example from mdn:

const items = ['réservé', 'communiqué', 'café', 'adieu', 'éclair'];

items.sort(function (a, b) {
  return a.localeCompare(b);
});

console.log(items);
// Output: ["adieu", "café", "communiqué", "éclair", "réservé"]

Note: The localeCompare method returns a number indicating whether a reference string comes before, or after, or is the same as the given string in sort order.

Sorting Array Elements Numerically

To sort numbers, you can use the Array.prototype.sort method, but as long as array items are converted to strings and compared in UTF-16 code units, all you need is a simple trick.

But let's once sort an array of numbers without applying that trick and see the result:

const numbers = [9, 1, 80, 100];

numbers.sort();

console.log(numbers);
// Output: [1, 100, 80, 9]

The array got sorted alphabetically, so each integer actually got coerced into a string type. Then each string was compared, which is why 80 came before 9 and 100 came before 80 — strings are compared character-by-character.

The solution to achieve a numeric sort is passing a comparison (a, b) => a - b function to the sort method as a parameter.

const numbers = [9, 1, 80, 100];

numbers.sort(function (a, b) {
  return a - b;
});

console.log(numbers);
// Output: [1, 9, 80, 100]

As you see the array is sorted numerically, but let's see what happens under the hood.

If the compareFunction parameter is passed to the sort method, all non-undefined array elements are sorted according to the return value of the compare function. If two elements, a and b, are being compared, then:

  • Sort b before a, if compareFunction(a, b) returns a value > 0
  • Leave a before b in the same order, if compareFunction(a, b) returns a value ≤ 0

So, the compare function can have something like this under the hood mdn:

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
    return -1;
  }

  if (a is greater than b by the ordering criterion) {
    return 1;
  }

  // a must be equal to b
  return 0;
}

Ascending Sort

To sort an array numerically in ascending order, the comparison function (a, b) => a - b should return the difference between the two numbers.

const numbers = [8, -2, 10, 100, 19, -4, -10];

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

console.log(numbers);
// Output: [-10, -4, -2, 8, 10, 19, 100]

The comparison function (a, b) => a - b subtracts the second item from the first, returning a negative value if the second item is bigger, a positive value if the second item is smaller, and zero if the two items are equal.

Descending Sort

A descending sort would just need the operators reversed, so the comparison function becomes (a, b) => b - a.

const numbers = [8, -2, 10, 100, 19, -4, -10];

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

console.log(numbers);
// Output: [100, 19, 10, 8, -2, -4, -10]

Use-case

Consider the following array which each element of it is an object, holding two properties of name and score:

const results = [
  { name: 'Edward', score: 87 },
  { name: 'Williams', score: 50 },
  { name: 'Andy', score: 45 },
  { name: 'Ella', score: 75 },
  { name: 'Alex', score: 68 },
  { name: 'Mason', score: 37 }
];

The use-case is to sort the results array once according to the names and once according to the score in ascending orders.

Give it a try and then look at the solution!

Hint: Arrays of objects can be sorted by comparing the value of one of their properties.

Note: The idea of the use-case is taken from mdn!

Let's do it!

As mentioned above in the hint, arrays whose elements are objects can be sorted by comparing the value of one of their properties. So let's start with sorting the results array according to the score property:

// Make a shallow copy
const resultsSortedAccordingToScore = [...results];

// Sort in ascending order
resultsSortedAccordingToScore.sort(function (a, b) {
  return a.score - b.score;
});

console.log(resultsSortedAccordingToScore);
/*
 * (6) [{…}, {…}, {…}, {…}, {…}, {…}]
 *   0: {name: "Mason", score: 37}
 *   1: {name: "Andy", score: 45}
 *   2: {name: "Williams", score: 50}
 *   3: {name: "Alex", score: 68}
 *   4: {name: "Ella", score: 75}
 *   5: {name: "Edward", score: 87}
 */

As you see, the resultsSortedAccordingToScore has been sorted according to the score property.

In the next step, let's sort the results array according to the name property:

// Make a shallow copy
const resultsSortedAccordingToName = [...results];

// Sort in ascending order
resultsSortedAccordingToName.sort(function (a, b) {
  let nameA = a.name.toLowerCase();
  let nameB = b.name.toLowerCase();

  if (nameA < nameB) {
    return -1;
  }

  if (nameA > nameB) {
    return 1;
  }

  // names must be equal
  return 0;
});

console.log(resultsSortedAccordingToName);
/*
 * (6) [{…}, {…}, {…}, {…}, {…}, {…}]
 *   0: {name: "Alex", score: 68}
 *   1: {name: "Andy", score: 45}
 *   2: {name: "Edward", score: 87}
 *   3: {name: "Ella", score: 75}
 *   4: {name: "Mason", score: 37}
 *   5: {name: "Williams", score: 50}
 */

As you see the output, the array has been sorted according to the name property of the results array but was a little bit tricky.

In the first step, I converted all the letters of name properties to lower case letters (or upper case letters) to do a case-insensitive comparison.

Note: The Alex and alex are different strings because a and A holds different Unicode code point values.

Conclusion

The JavaScript sort method orders the elements of an array alphabetically in ascending order by default. The sort modifies an array in place which means the method does not return a new sorted array. In order to sort an array in descending order, instantly invoke Array.prototype.reverse method after the array has been sorted.

In this article, I have broken down how to sort an array in JavaScript using sort method in either ascending and descending orders, both numerically and alphabetically, and at the end, I provided a real-life use-case example for a better understanding of the subject.

Before you leave

If you would love to read even more content like this, feel free to visit me on Twitter or LinkedIn.

I'd love to count you as my ever-growing group of awesome friends!