For more tips like this, sign up to the weekly newsletter!

Why reverse sorting is not the same as sorting and reversing

When you have an array of objects, and you sort by a property, you can easily get an ascending short:

.sort((n1, n2) => n1 - n2)

But when you need to sort descending, you have two options: Either sort then reverse or sort by multiplying the sorting result by -1. In code:

.sort((n1, n2) => n1 - n2).reverse()
.sort((n1, n2) => (n1 - n2) * -1)

Is there a difference?

Yes, there is.

For a simple list of numbers, it does not matter, the result will be the same:

[4, 5, 1].sort((n1, n2) => n1 - n2) // [1, 4, 5]
[4, 5, 1].sort((n1, n2) => (n1 -n2) * -1) // [5, 4, 1]
[4, 5, 1].sort((n1, n2) => n1 - n2).reverse() // [5, 4, 1]

Even for objects, in the simplest case, it does not matter:

const users = [
  {
    name: "user2",
    score: 5,
  },
  {
    name: "user3",
    score: 8,
  },
  {
    name: "user1",
    score: 3,
  }
];
[...users].sort((u1, u2) => u1.score - u2.score) // user1, user2, user3
[...users].sort((u1, u2) => (u1.score - u2.score) * -1) // user3, user2, user1
[...users].sort((u1, u2) => u1.score - u2.score).reverse() // user3, user2, user1

Duplicated elements

The difference surfaces when there are duplicated elements:

const users = [
  {
    name: "user2",
    score: 5,
  },
  {
    name: "user4",
    score: 8,
  },
  {
    name: "user1",
    score: 3,
  },
  {
    name: "user3",
    score: 5,
  },
];
[...users].sort((u1, u2) => u1.score - u2.score) // user1, user2, user3, user4
[...users].sort((u1, u2) => (u1.score - u2.score) * -1) // user4, user2, user3, user1
[...users].sort((u1, u2) => u1.score - u2.score).reverse() // user4, user3, user2, user1

In this case, the two approaches produces different results.

Why is that?

Stable sorting

The answer is stable sorting. When two items are considered the same, the sorting does not change their relative positions. And most javascript engines use a stable sorting algorithm.

That's why multiplying by -1 does not actually reverse the ordering, but leave same object in place.

Try it
Learn more: