Understanding Array.sort compareFn
Tags: javascript, beginners, programming
Published: 2023-02-04 14:06:33

> Understanding Array.sort compareFn

With `compareFn` which is an option of `sort`, you can sort elements in an order that you want.


[compareFn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort): Specifies a function 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.

In the documentation, in order to use `compareFn`, you should read it thoroughly

- A comparator conforming to the constraints above will always be able to return all of 1, 0, and -1, or consistently return 0. For example, if a comparator only returns 1 and 0, or only returns 0 and -1, it will not be able to sort reliably because anti-symmetry is broken. A comparator that always returns 0 will cause the array to not be changed at all, but is reliable nonetheless.

---

Let's begin with a number array.

```javascript
const arr = [4, 3, 1, 5, 2];

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

console.log(arr);

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

console.log(arr);
```

```
[ 1, 2, 3, 4, 5 ]
[ 5, 4, 3, 2, 1 ]
```

I sorted it in ascending and reversed.

What do value `a` and `b` have?
Let's print it out.

```javascript
const arr = [4, 3, 1, 5, 2];

arr.sort((a, b) => {
  console.log(a, b);
  return a - b;
});
```

```
3 4
1 3
5 1
5 3
5 4
2 4
2 3
2 1
```

In the result, only one thing we should know that `a` element is next element of `b` element.

Let's say. We want to place a specific value `3` at the first position.

We can do like this.

```javascript
const arr = [4, 3, 1, 5, 2];

arr.sort((a, b) => {
  if (a === 3) return -1;
  else if (b === 3) return 0;

  return a - b;
});

console.log(arr);
```

```
[ 3, 1, 2, 4, 5 ]
```

---

We are also be able to sort an object array.

```javascript
const objArr = [
  {
    name: "Bob",
    age: 30,
  },
  {
    name: "Delta",
    age: 23,
  },
  {
    name: "Charlie",
    age: 25,
  },
  {
    name: "Echo",
    age: 29,
  },
  {
    name: "Charlie",
    age: 25,
  },
  {
    name: "Alice",
    age: 20,
  },
];
```

Let's try to sort it by age in ascending.

```javascript
const objArr = [
  {
    name: "Bob",
    age: 30,
  },
  {
    name: "Delta",
    age: 23,
  },
  {
    name: "Charlie",
    age: 25,
  },
  {
    name: "Echo",
    age: 29,
  },
  {
    name: "Alice",
    age: 20,
  },
];

objArr.sort((a, b) => {
  return a.age - b.age;
});

console.log(objArr);
```

```
[
  { name: 'Alice', age: 20 },
  { name: 'Delta', age: 23 },
  { name: 'Charlie', age: 25 },
  { name: 'Echo', age: 29 },
  { name: 'Bob', age: 30 }
]
```

We can sort it by string using [String.localeCompare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare).

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

You can check out more details about the function in the document.

For the first, let's see results of the function.

```javascript
console.log("a".localeCompare("a"));
console.log("a".localeCompare("b"));
console.log("b".localeCompare("a"));
```

```
0
-1
1
```

When the parameter comes after the string, it returns `-1`.
In other words, when the string comes before the parameter, it returns `-1`.

Just pick two names that has to be switched.
I picked `Charlie` and `Delta`.
To switch these, we have to return `-1.`.
The element that has `Charlie` comes after the element that has `Delta`, right?

So, `a` will be an element that has `Charlie` and `b` will be an element that has `Delta`.

```javascript
"Charlie".localeCompare("Delta");
```

It will return `-1`. 

It means

```javascript
a.name.localeCompare(b.name);
```

This will be our `compareFn` function.
Okay, let's sort the object array by `name`.

```typescript
const objArr = [
  {
    name: "Bob",
    age: 30,
  },
  {
    name: "Delta",
    age: 23,
  },
  {
    name: "Charlie",
    age: 25,
  },
  {
    name: "Echo",
    age: 29,
  },
  {
    name: "Alice",
    age: 20,
  },
];

objArr.sort((a, b) => {
  return a.name.localeCompare(b.name);
});

console.log(objArr);
```

```
[
  { name: 'Alice', age: 20 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 25 },
  { name: 'Delta', age: 23 },
  { name: 'Echo', age: 29 }
]
```

It works well.

Let's say we have to place an element that has a name `Charlie` at the first.

When `a` is `Charlie`, we should return `-1`, and when `b` is `Charlie`, we should keep it as consistency.

```javascript
const objArr = [
  {
    name: "Bob",
    age: 30,
  },
  {
    name: "Delta",
    age: 23,
  },
  {
    name: "Charlie",
    age: 25,
  },
  {
    name: "Echo",
    age: 29,
  },
  {
    name: "Alice",
    age: 20,
  },
];

objArr.sort((a, b) => {
  if (a.name === "Charlie") return -1;
  if (b.name === "Charlie") return 0;
  return a.name.localeCompare(b.name);
});

console.log(objArr);
```

```
[
  { name: 'Charlie', age: 25 },
  { name: 'Alice', age: 20 },
  { name: 'Bob', age: 30 },
  { name: 'Delta', age: 23 },
  { name: 'Echo', age: 29 }
]
```

That's it!
I hope you found it useful.

Happy Coding!