Comparing Arrays in JavaScript

Hero image for Comparing Arrays in JavaScript. Image by Scott Webb.
Hero image for 'Comparing Arrays in JavaScript.' Image by Scott Webb.

Much like manipulating array data by appending and prepending elements, comparing two arrays in JavaScript is a very common task in frontend development but as is always the case there are a number of different options and methods to achieve this comparison, all with different benefits and drawbacks.


Using the toString() method

The simplest way to compare arrays is to convert them to strings, and then compare the two strings:

const array1 = [1, 2, 3, 4];const array2 = [1, 2, 3, 4];const areEqual = array1.toString() === array2.toString();console.log(areEqual ? 'The arrays are equal' : 'The arrays are not equal');//=> 'The arrays are equal'

Using the JSON.stringify() method

In almost exactly the same way as above, we can convert both arrays into JSON strings, and then use the strict equality operator to compare the two. Depending on the size and complexity of your array, this may be marginally more performant than converting the arrays to strings:

const array1 = [1, 2, 3, 4];const array2 = [1, 2, 3, 4];const areEqual = JSON.stringify(array1) === JSON.stringify(array2);console.log(areEqual ? 'The arrays are equal' : 'The arrays are not equal');//=> 'The arrays are equal'

It is worth bearing in mind that this method will only work if both objects are JSON serialisable, and do not contain cyclic references. Otherwise, you may see a TypeError:

TypeError: Converting circular structure to JSON

Use a Comparative, Recursive Function

The final and potentially most robust option is to write a recursive, looping function to do a deep comparison of each array by looping over each individual element. This is best achieved in a utility function, with some simple gatekeeping. It could look something like this:

const arraysAreEqual = (a, b) => {  const isArrayA = Array.isArray(a);  const isArrayB = Array.isArray(b);  // type check: if one is an array and the other isn't  if (isArrayA !== isArrayB) {    return false;  }  // strict equality check (if neither are arrays)  if (!(isArrayA && isArrayB)) {    return a === b;  }  // at this point we know they are both arrays, so use a  // simple length check to see if they are equal.  if (a.length !== b.length) {    return false;  }  // iterate over array 'a', and compare against the same  // element in 'b' by calling arraysAreEqual recursively  a.forEach((element, index) => {    if (!arraysAreEqual(element, b[index])) {      return false;    }  });  // finally, if all other checks have passed, then...  return true;};console.log(arraysAreEqual([1, 2, 3, 4], [1, 2, 3, 4]));//=> true

I've added comments to the snippet above to offer some guidance, but to describe what's going on in more detail: this function accepts two arrays as parameters and returns true if they are equal, and false otherwise.

In order to keep the function as performant as possible, we want to return false as early as we can, so we work our way through progressively more complex comparisons:

  1. First, we check if both parameters passed are arrays.
  2. We can immediately return false if we know that the parameter types don't match (for example if one is an array and the other is a string).
  3. If neither are arrays, we return a strict equality check between the two parameters (this is useful when it comes to calling the function recursively later on).
  4. We now know that both parameters are arrays, so we compare their lengths; naturally, if they are of different lengths then they cannot be equal, so we return false.
  5. If we have gotten to this point, we can now start comparing each individual element by passing them back into the function. If at any point these individual elements do not match, then we can return false.
  6. Finally, if all of the above has passed, then we can be sure that the two arrays match and we can return true.

It is important to note that this function assumes that the arrays do not contain circular references and that their elements are either primitives or arrays themselves. If you need to handle more complex cases, you would need to modify the function accordingly.

For completeness' sake, you should wrap this in a try and catch, if you intend to use it in production, or if there is the slightest change that data passed into it may contain cyclic references.


Choosing the Right Solution

As I mentioned, each method of array comparison in JavaScript has its own benefits and drawbacks, and only you will know which is most suitable for your specific use case. Here are a few factors worth considering:

Speed

Some methods may be faster than others, depending on the size and complexity of the arrays. For example, using a loop to compare arrays may be faster than converting them to strings or JSON, but it may not be the best choice for very large arrays.

Complexity

Some methods may be more complex than others, especially if you need to handle edge cases or nested arrays. Using JSON.stringify() is a simple and reliable way to compare arrays, but it may not work if the arrays contain functions or circular references.

Flexibility

Some methods may be more flexible than others, allowing you to customize the comparison logic to your specific needs. Using (and modifying) the recursive, looping example I've given above may give you the most control over how the arrays are compared, but it will require more code to handle complex cases and may be less performant.

Readability

Some methods may be more readable than others, making your code easier to understand and maintain. Using JSON.stringify() or toString() may be more concise and easier to read than a much larger utility function, especially if you don't need to handle complex cases.


The Wrap‑Up

Ultimately, the best method for comparing arrays depends on your specific use case and requirements. You should consider factors such as speed, complexity, flexibility, and readability when choosing which method to use, but hopefully, the three examples I've shared today will help you along the way.


Categories:

  1. Adaptive Development
  2. Front‑End Development
  3. JavaScript
  4. Responsive Development