All Articles# Understanding Javascript's Array.prototype.sort beyond 1 to 9

### Weirdness beyond One, Two, Three

### Take away

*If you have programmed in javascript, chanceβs are you would have come across Array.prototype.sort. Sometimes it does what you
want, other times it does what it wants. In this article we will try to understand Array.prototype.sort beyond 1 - 9.*

If you have had to use this method, like me you can recall having to tweak operators to do what you want.
Well, try `a + b`

first (which never does what you want), then `a - b`

, occasionally an explicit ternary π.

It feels very intuitive and seemingly simple to use but not quite straight-forward to understand. Here is the signature;

```
const array = [1,4,3,2,7]
array.sort((a, b) => a - b);
```

- a - first element, or left hand side element
- b - second element, or right hand side element

The comparator `(a,b) => a - b`

is expected to return

- A negative value if
`a < b`

- A positive value if
`a > b`

- Zero if the first and second arguments are equal. Thus
`a = b`

```
const positions = [1,5,7,3,9]
const sorted = [...positions].sort((a, b) => a - b)
console.log(sorted) // [1, 3, 5, 7, 9]
//OR
const sortWithoutCompareFn = [...positions].sort()
console.log(sortWithoutCompareFn) // [1, 3, 5, 7, 9]
```

**Sort without a comparator**

```
const positions = [1,5,7,3,9, 10, 100]
positions.sort()
console.log(positions) // [1, 10, 100, 3, 5, 7, 9] βοΈ
```

Briefly, if the `comparator`

is not provided, then the sort order is ascending/alphabetical. The caveat is that, numbers are converted to strings and their
UTF-16 unit values are compared hence the unintuitive position of `10`

and `100`

above. Basically *β1β* (β1β, β10β, β100β) is smaller that *β3β*.

If you are keen on how the abstract relation comparison works, step 3c. This is easy to fix by providing a compare function.

**Recap Sort with a comparator**

```
const positions = [1,5,7, 10, 100, 3,9]
const sorted = [...positions].sort((a, b) => a - b)
console.log(sorted) // [1, 3, 5, 7, 9, 10, 100]
```

This behaviour is fairly straight-forward and will behave as intended as long as your comparator returns a number. The expression `Number(campareFn(a,b))`

should not evaluate to `NaN`

otherwise `a`

and `b`

are considered equal thus 0 is returned !.

```
const positions = [1,5,7, 'a', 10, 100, 3,9]
const sorted = [...positions].sort((a, b) => a - b)
console.log(sorted) // [1, 5, 7, "a", 3, 9, 10, 100] βοΈ
```

This again is easy to fix by providing a compare function

```
const positions = [1,5,7, 'a', 10, 100, 3,9]
const sorted = [...positions].sort((a, b) => a > b ? 1 : -1)
console.log(sorted) // ["a", 1, 3, 5, 7, 9, 10, 100] β
```

**The undefined**

```
const positions = [1, 3, undefined, 5, 2]
const sorted = [...positions].sort((a, b) => a - b)
console.log(sorted) // [1, 2, 3, 5, undefined]
```

`undefined`

always compare greater than any value. Here a few simple rules;

- If a and b are both undefined, 0 is returned thus elements are equal.
- If a is undefined, return 1.
- If b is undefined, return -1.

To achieve a more deterministic or consistent result, always provide a compare function! Until next time, stay curious !

Published on *January 2020*