The Only JavaScript Sorting Guide You'll Ever Need
Tags: javascript, webdev, tutorial, programming
Published: 2022-04-15 18:19:30

## Table Of Contents
<ul>
  <li><a href="#hello-reader">Hello Reader</a></li>
  <li><a>JavaScript's sort() function</a></li>
    <ul>
      <li><a href="#implementation-history">Implementation History</a></li>
    </ul>
  </li>
  <li><a href="#sorting-primitives">Sorting Primitives</a></li>
  <ul>
    <li><a href="#array-of-strings">Array of Strings</a></li>
    <li><a href="#array-of-numbers">Array of Numbers</a></li>
    <ul>
      <li><a href="#compare-function">Compare Function</a></li>
      <li><a href="#descending-order">Descending Order</a></li>
    </ul>
  </ul>
  <li><a"#sorting-an-array-of-objects">Sorting an Array of Objects</li>
  <li><a href="#final-thoughts">Final Thoughts</a></li>
</ul>

---

## Hello Reader 👋🏽
I was tired of searching on Google when I was unsure of how to sort whatever data I'm using in JavaScript, so I decided to write it all in one place.

Today, we are going to learn about sorting in JavaScript. Starting with the history and algorithm used for `.sort()`. Then learning how to sort primitives and objects. Let's jump in!

## JavaScript's sort() function 📏
The `.sort()` function sorts an array in-place (meaning no copy is made) and returns the sorted array. We **can't** modify the algorithm used by `.sort()`, but we **can** modify how it compares array elements by passing a `compare function`.

```javascript
// Native, without a compare function
sort()

// With an arrow pointing compare function
sort((a, b) => {
 ...
})

// Passing a compare function
sort(compareFn)
```

### Implementation History
In Chrome, back in the ye-old days, the sorting algorithm wasn't as good as today. One of its previous implementations included **insertion sort** O(n<sup>2</sup>) 🤢.

Today we are in a better state with a modification of **Merge Sort** named **Tim Sort** O(n log n) 😊. Initially created by Time Peters as an adaptive stable Merge Sort variant.

> A stable sorting algorithm means if two values of the same value sit next to each other, they maintain the same order after sorting. You'd be surprised how many algorithms depend on this.


## Sorting Primitives
Let's go over how to sort primitives with `.sort()`.

## Sorting an Array of Strings
The `sort()` function works how you'd expect for strings.

```javascript
const names = ["Darui", "Bee", "Naruto", "Ada", "Sasuke", "Baki", "A"];

console.log(names.sort());
```

```javascript
// Output: ["A", "Ada", "Baki", "Bee", "Darui", "Naruto", "Sasuke"]
```

JavaScript by default sorts in **Lexicographical** order. Lexicographical order means sorted alphabetically sort of like a dictionary. If two strings are equal, then the shortest one is put first.

```javascript
// Lexicographical order
const str = ["aab", "ba", "aac", "bab", "aaa", "Aab", "aaaa"];

// Results
"Aab" // Uppercase letters take precedence
"aa|a"
"aa|aa" // Is equal to "aaa" but is longer
"aa|b" // The 3rd char 'b' comes the third char 'a' in the strings above.
"aa|c" // The last char 'c' comes after 'b'
"ba" // The first char 'b' comes after 'a' in the above strings
"bab"
```

## Sorting an Array of Numbers 🧮
Using `.sort()` on numbers is a bit tricky. It **DOES NOT** work natively.

```javascript
const scores = [9, 80, 19, 4, 20, 53];

// Wrong ❌
console.log(scores.sort());
```

```javascript
// Wrong order 👎🏽
// Output: [19, 20, 4, 53, 80, 9]
```

By default, JavaScript sorts in **Lexicographical** order. Great for strings but terrible for numbers. We have to pass a `compare function`.

<figure>
  <img src="https://i.kym-cdn.com/entries/icons/mobile/000/023/397/C-658VsXoAo3ovC.jpg" />
  <figcaption>Who gets sorted first?</figcaption>
</figure>
---

### Compare Function
<figure>
  <img src="https://i.imgur.com/T3MBeKB.png" />
  <figcaption>Compare function interpretation</figcaption>
</figure>
---

The `compare function` returns an integer which `.sort()` uses to determine the order when comparing elements.

```javascript
function compareNumbers(a, b) {
  if (a < b) {
    return -1; // sort a before b
  } else if (a > b) {
    return 1; // sort a after b
  }

  return 0; // keep a and b in the same order
}
```

When two elements are passed to the `compare function`, if it returns less than 0, `a` is put first. If the result is greater than 0, `b` is put first. If the result is equal to 0, keep `a` and `b` in the same order. Ex. `a(3) - b(2)` is 1 which puts `b(2)` in front of `a(3)`.

To properly sort numbers, we introduce a `compare function` to sort numbers in ascending order.

```javascript
let scores = [9, 80, 19, 4, 20, 53];

// Sort in ascending order ✅
scores.sort((a, b) => {
  return a - b;
});

console.log(scores);
``` 

```javascript
// Output: [4, 9, 19, 20, 53, 80]
```

### Descending Order
Descending order is an easy 1 line change. Instead of using `a - b`, use `b - a` to reverse the order. Take our `a(3) - b(2)` example from earlier. If we change it to `b(2) - a(3)`, we get -1. This instead puts `a(3)` in front of `b(2)`.

```javascript
let scores = [9, 80, 19, 4, 20, 53];

// Sort in descending order
scores.sort((a, b) => {
  return b - a;
});

console.log(scores);
```

```javascript
// Output: [80, 53, 20, 19, 9, 4]
```

## Sorting an Array of Objects 🏎️
In JavaScript, an object is a variable with a collection of  properties in `key:value` pairs.

```javascript
// Array of objects with two properties, 'name' and 'titansDefeated'.
const characters = [{
    name: 'eren',
    titansDefeated: 1
  },
  {
    name: 'mikasa',
    titansDefeated: 20
  },
  {
    name: 'levi',
    titansDefeated: 90
  },
  {
    name: 'armin',
    titansDefeated: 10
  },
];
```

Since objects have multiple properties, we pass a `compare function` to sort by the property we want.

Sorting by the amount of `titansDefeated` in **ascending** order.

```javascript
const characters = [{
    name: 'eren',
    titansDefeated: 1
  },
  {
    name: 'mikasa',
    titansDefeated: 20
  },
  {
    name: 'levi',
    titansDefeated: 90
  },
  {
    name: 'armin',
    titansDefeated: 10
  },
];

characters.sort((a, b) => {
  return a.titansDefeated - b.titansDefeated;
});

console.log(characters);
```

```javascript
// Output: [{
//  name: "eren",
//  titansDefeated: 1
// }, {
//  name: "armin",
//  titansDefeated: 10
// }, {
//  name: "mikasa",
//  titansDefeated: 20
// }, {
//  name: "levi",
//  titansDefeated: 90
// }]
```

Sorting by the amount of `titansDefeated` in **descending** order.

```javascript
const characters = [{
    name: 'eren',
    titansDefeated: 1
  },
  {
    name: 'mikasa',
    titansDefeated: 20
  },
  {
    name: 'levi',
    titansDefeated: 90
  },
  {
    name: 'armin',
    titansDefeated: 10
  },
];

characters.sort((a, b) => {
  return b.titansDefeated - a.titansDefeated;
});

console.log(characters);
```

```javascript
// Output: [{
//  name: "levi",
//  titansDefeated: 90
// }, {
//  name: "mikasa",
//  titansDefeated: 20
// }, {
//  name: "armin",
//  titansDefeated: 10
// }, {
//  name: "eren",
//  titansDefeated: 1
// }]
```

Sorting by `names` in **lexicographical** order.

```javascript
const characters = [{
    name: 'eren',
    titansDefeated: 1
  },
  {
    name: 'mikasa',
    titansDefeated: 20
  },
  {
    name: 'levi',
    titansDefeated: 90
  },
  {
    name: 'armin',
    titansDefeated: 10
  },
];

// Sort names in case-insensitive
// lexicographical order
characters.sort((a, b) => {
  // Convert to uppercase so we don't have
  // to worry about case differences.
  const nameA = a.name.toUpperCase();
  const nameB = b.name.toUpperCase();

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

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

console.log(characters);
```

```javascript
// Output:[{
//  name: "armin",
//  titansDefeated: 10
// }, {
//  name: "eren",
//  titansDefeated: 1
// }, {
//  name: "levi",
//  titansDefeated: 90
// }, {
//  name: "mikasa",
//  titansDefeated: 20
// }]
```

<figure>
  <img src="https://64.media.tumblr.com/43d95dfb40978c57175c6caa1d7d2b71/tumblr_ps4fvfbWu21vfdmp1o1_540.gifv" />
  <figcaption>Levi said "sort faster"</figcaption>
</figure>
---

## Final Thoughts 💭
Here's everything you need for sorting in JavaScript all in one place. In Chrome, `.sort()` is implemented using the **Tim Sort** algorithm. By default `.sort()` sorts in lexicographical order, great for strings but not so much for anything else. We pass a `compare function` for numbers and objects to define the sorting order.

I'm Gregory Gaines, a goofy software engineer @Google who's trying to write good articles. If you want more content, follow me on Twitter at <a href="https://twitter.com/GregoryAGaines" target="_blank">@GregoryAGaines</a>.

Now go create something great! If you have any questions, hit me up on Twitter (<a href="https://twitter.com/GregoryAGaines" target="_blank">@GregoryAGaines</a>); we can talk about it.

Thanks for reading!