How to sort an array of objects in javascript

How to sort an array of objects in javascript

How would you sort a given array of objects in javascript?

const numbers = [
  {
    value: 2,
    order: 'two',
    isEven: true
  },
  {
    value: 3,
    order: 'three',
    isEven: false
  },
  {
    value: 5,
    order: 'five',
    isEven: false
  },
]

To sort such an array with any accuracy you'll first need to figure out the property value you want to use in sorting it. Depending on the data type of said property value, the approach we take can differ. Here's how we can handle it if the property value is an;

Integer

ascending order

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

descending order

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

String

ascending order

numbers.sort((a,b) => a.order.toLowerCase().localeCompare(b.order.toLowerCase()))

descending order

numbers.sort((a,b) => b.order.toLowerCase().localeCompare(a.order.toLowerCase()))

Boolean

ascending order (false comes first)

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

descending order (true comes first)

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

Why does comparing booleans as though they were numbers work? I'm not sure myself but if you think about it, if 0 or -1 which is falsy is less than 1 which is truthy, then false is less than true, and true is greater than false.

What if we wanted to do something a little more complex? Say, rearrange our array such that all the objects with the isEven property set to true came first but the objects were still sorted according to their numerical value? Well, keep in mind that we can always chain a sort() method to another one.

numbers.sort((a,b) => b.isEven - a.isEven).sort((a,b) => a.value - b.value)

We can also write this more concisely using only one sort() as;

numbers.sort((a,b) => b.isEven - a.isEven && a.value - b.value)

Although the argument could be made that the latter approach is harder to read.

Okay, I have one more advanced use case left in me and I only stumbled on this fairly recently. What if we wanted to sort an array of objects based on a property that they don't all share? We'll need a new numbers array to demonstrate this.

const numbers = [
  {
    value: 3,
    order: 'three',
    isEven: false,
    isPrime: 'yes'
  },
  {
    value: 2,
    order: 'two',
    isEven: true,
    isPrime: 'yes'
  },
  {
    value: 5,
    order: 'five',
    isEven: false,
    isPrime: 'yes'
  },
  {
    value: 6,
    order: 'six',
    isEven: false
  },
]

You'll notice that the very last object in our new numbers array does not have an isPrime property. I'd leave you to find out what happens if you try to approach it like any of the use cases given above but here's how you can handle sorting an array of dissimilar objects based on a property they don't all share in;

ascending order (the objects without the property come first)

numbers.sort((a,b) => Boolean(a.isPrime) - Boolean(b.isPrime))

and descending order (the objects with the property come first)

numbers.sort((a,b) => Boolean(b.isPrime) - Boolean(a.isPrime))

One quick "gotcha" that I have to mention is that the sort() method (for reasons unknown to me) mutates an array before returning it. This can lead to some confusion when you're using other instances of your array in the same scope so just keep this in mind. You can read up on this unexpected behavior here.