Sorting Objects in JavaScript

Hero image for Sorting Objects in JavaScript. Image by Tim Gouw.
Hero image for 'Sorting Objects in JavaScript.' Image by Tim Gouw.

When working with arrays of objects in JavaScript, the Array.prototype.sort() method requires a bit more finesse simply because you are dealing with properties of objects rather than individual values.


Understanding Comparator Functions for Objects

A comparator function for sorting an array of objects must be provided to the sort() method in order to define the specific property or properties that you want the object sorted by.

This function should take two parameters (conventionally, these are named a and b), which represent the objects being compared.


The Comparator's Return Values

The comparator function must return a value that tells the sort() method how to order the two elements a and b:

  • If it returns a negative number, sort() will place a before b.
  • If it returns zero, it will leave a and b unchanged with respect to each other, but sorted with respect to all different elements.
  • If it returns a positive number, sort() will place b before a.

Sorting Objects by a Numeric Property

The most common use case I come across for sorting an array of objects is numerically. For example: sorting products by their prices, or electric vehicles by battery range, or even flights by number of layovers.

So, suppose we have an array of objects where each object has a price property and we want to sort the array in ascending order of prices:

const products = [  {    name: 'iPhone 13 mini',    price: 699,  },  {    name: 'iPhone SE (3rd generation)',    price: 429 },  {    name: 'iPhone 13 Pro',    price: 999,  },  {    name: 'iPhone 13 Pro Max',    price: 1099,  },  {    name: 'iPhone 13',    price: 799,  },];products.sort((a, b) => a.price - b.price);

Here, the comparator function (a, b) => a.price b.price calculates the difference between the price of each product. If a is less expensive than b, then it returns a negative value, placing a before b.


Sorting Objects by a String Property

If you want to sort by a string property, such as the name of a product, you'll need a different approach since you cannot subtract strings.

I also need to use a different example here because sorting by different iPhone models when they all start with the word 'iPhone' isn't terribly illustrative! So, here goes:

const products = [  { name: 'Notebook', price: 9.99 },  { name: 'Pencil', price: 1.7 },  { name: 'Backpack', price: 19.99 },];products.sort((a, b) => {  if (a.name < b.name) {    return -1;  }  if (a.name > b.name) {    return 1;  }  return 0;});

In this example, the comparator function uses the less than (<) and greater than (>) operators to compare the name properties lexicographically. It returns 1 or 1 to determine the order of a and b respectively, or 0 if they are equal.

A Brief Note on Deeper String Sorting

It may not be obvious, but if you compare two string properties that start with the same letter (for example: 'car' and 'camera'), then the sort() method will continue to compare the subsequent characters in the strings to determine their lexicographic order.

Here's a quick rundown of how the comparison would work if two product names start with the same letter:

  1. The first characters of both strings (a.name and b.name) are compared.
  2. If the characters are the same (e.g., both are 'C'), the comparison moves to the next pair of characters.
  3. This process continues until a pair of characters differs.
  4. The string with the character that comes first in the Unicode code points is considered "less" than the other string and will be positioned first after sorting.

Dealing with Case Sensitivity

When sorting by string values, it is important to be aware that sorting by strings is casesensitive. The string 'banana' will come before 'Apple' because lowercase letters have higher values in the Unicode table than uppercase letters.

Fortunately, this is relatively easy to get around. If you want to sort strings in a caseinsensitive manner, you must first standardise the case within your comparator function:

products.sort((a, b) => {  const nameA = a.name.toLowerCase();  const nameB = b.name.toLowerCase();  if (nameA < nameB) {    return -1;  }  if (nameA > nameB) {    return 1;  }  return 0;});

Generally, there's no risk in comparing your strings in lowercase when passing them through the comparator; this doesn't mutate the original data, and even if you are confident in your data, it could avoid an edge case where a capital letter sneaks its way in.


The Wrap‑Up

Sorting an array of objects requires a comparator function tailored to the specific property or properties you want to sort (and how). Whether dealing with numeric values, strings, or even more complex data structures, the comparator function is key to ensuring your objects are sorted in the desired order.

By understanding how to craft these functions, you can harness the full power of the Array.prototype.sort() method to organise your data structures effectively and avoid any weirdness that otherwise comes from lexicographic sorting!


Categories:

  1. Development
  2. Front‑End Development
  3. Guides
  4. JavaScript