LetMyPeopleCode.com

A blog about software, schmaltz, and monkey-patches for the soul

Menu
  • About Greg Bulmash
  • Greg Talks Tech
  • Privacy Policy
Menu
comparing

Comparing Two Arrays in Any Order (JavaScript)

Posted on February 10, 2022February 10, 2022 by Greg Bulmash

How do you tell if two arrays are equal regardless of the order of their values?

In doing some programming exercises in preparation for interviews, I ran across a task that required me to compare two arrays of integers that could come in any order. I went and Googled whether there was a simple way of doing this. Not only did it seem there isn’t, but there were a LOT of answers that were wrong.

Problem 1: JavaScript Arrays Pass By Reference

Simply trying to compare arrays is not going to work.

let a = [1,2,3]; 
let b = [1,2,3]; 
console.log(a === b) // false
let a = [1,2,3]; 
let b = a; 
console.log(a === b) // true

Array variables contain a pointer to the array structure in memory, not its values, so two arrays will be compared as pointers. If they are each an individual array (first sample), the comparison will come up false because they point to two different objects. Because arrays are passed by reference (the pointer), if you just copy the pointer into b instead of creating a second array, the comparison works.

But because the array is passed by reference, what you do to b will happen to a. So to compare your arrays, you need to compare them value by value.

Problem 2: How Do You Handle Any Order?

There are basically two ways to handle this and each comes with their own considerations.

The first is to just sort the two arrays before comparing them. Then it’s an index-to-index comparison. If they contain the same values, the sorted arrays will match place for place.

The second is the one I use as solution 1. That is to make a copy of one array, then as its members are matched against the other array, drop them out of the array.

A Primary Consideration

Remember how I said arrays are passed by reference? That happens when you pass them to a function too. If your function sorts your arrays, they’ll be sorted throughout the software from that point on. You need to think about whether the original order needs to be preserved. If so, you should create a copy of the array and then sort it.

My 1st Solution

My solution preserves the contents and order of both arrays. The second operation, copying the array, uses the spread operator (…) to create a brand new array in arr1 containing the same values represented by first. The reason this is done is because splicing items out of the original array would change the array’s contents for the rest of the program.

Then I walk through arr2‘s values, using arr1‘s indexOf() method to to find out if an element in arr2 is in arr1. If it is, the splice() method is used to remove it from arr1 so it can’t be matched by a later value in arr2. If we get to a value in arr2 that isn’t in arr1, we return false.

If both the length check and the value comparison succeeded, we return true.

const equals = (first, arr2) => {
  // quit if the arrays aren't the same size
  if(first.length !== arr2.length) return false;
  // create a copy of the array we'll be manipulating
  let arr1 = [...first];
  //compare the arrays, looping through arr2 
  for(let c = 0; c < arr2.length; c++){
    let x = arr1.indexOf(arr2[c]);
    if(x === -1) return false;
    arr1.splice(x,1);
  }
  return true;
}

 

The downside of this is that every comparison requires a search through arr1. The larger arr1 is, the more the complexity goes up for those searches.

My 2nd Solution

This will assume we want to preserve the order in the original arrays and make copies of each before sorting them. If we don’t, we can drop the lines that copy them.

const equals = (first, second) => {
  // quit if the arrays aren't the same size
  if(first.length !== second.length) return false;
  // create copies of the arrays we'll be manipulating
  let arr1 = [...first]; 
  let arr2 = [...second];
  //sort the arrays
  arr1.sort(function(a, b) {return a - b;});
  arr2.sort(function(a, b) {return a - b;});
  //compare them
  return arr1.every(function(e,i){ return e === arr2[i]; });
}

 

Because this is comparing index-to-index, the search to find the element at index i is less complex than to find a matching element anywhere in the array, which should lower time on large arrays. But the copy operations (if needed), sort operations, and additional memory will create their own resource usage story.

Either approach works. I probably need to run a few tests to see which works best, with and without sorts and on different array sizes.

Related

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Posts

  • Job Hunt Diary 2023: Verizon Is Passive-Aggressive?
  • Job Hunt Diary 2023: Eliciting Responses
  • Job Hunt Diary 2023: And so on, and so on…
  • Job Hunt Diary 2023: Freelancing and warning words
  • Job Hunt Diary 2023: Not all job fairs are created equal

Archives

  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • September 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • November 2021
  • May 2021
  • April 2020
  • March 2020

Categories

  • Apps
  • Computing
  • Frameworks and Libraries
  • Games
  • Hacks
  • Hardware
  • JavaScript
  • Mac
  • Mobile
  • Other Art Projects
  • Productivity
  • Programming
  • Projects
  • Python
  • Society & Culture
  • Teaching Code
  • Tech Career
  • Uncategorized
  • WebTech
  • Writing

Tag Cloud

Adobe advertising bad ads browser hunt clown car code sample comcast commute copy writing CX design Developer Relations dev rel evernote game demo google drive hardware review health home office home studio internet interview questions j job hunt job hunt diary Mac magento meta-coding OneNote PEO productivity review speedtest t-mobile Windows xfinity

©2023 LetMyPeopleCode.com | Theme by SuperbThemes