DEV Community

Cover image for Symmetric Difference between two arrays in Vanilla JavaScript 🥓
sanderdebr
sanderdebr

Posted on

Symmetric Difference between two arrays in Vanilla JavaScript 🥓

If you want to find the elements belonging to one but not both of two given sets, you are looking for the .. symmetric difference!

In this tutorial we will build a function that calculates the symmetric difference between two given arrays, after applying a provided function to each item in both arrays.

You will learn about:

  • Set objects (ES6 set of unique item)
  • map() and filter() methods to loop through arrays.

symmetric diff

Let's say we have two arrays containing decimals numbers and we want to check if there are values which are not in both arrays after rounding them off downwards:

getSymmetricDifference([2.66, 3.44, 7.123], [2.44, 2.67, 6.48], Math.floor); 

The first thing we want to do is place our arrays inside Sets. The Set object lets us store values of any type, whether primitive values (data that is not an object) or object references. A value in a set may only occur once, which is useful for us.

We could just put our array inside the Set() parameters but we want to apply the given function on each item. So we'll use the map method to create a new array populated with the results of calling the function on each item:

const getSymmetricDifference = (a, b, fn) => {
  const setA = new Set(a.map(item => fn(item)));
  const setB = new Set(b.map(item => fn(item)));
}

Our variables setA and setB are now containing only the unique, rounded off values of our given arrays.

Next up we want to filter out any values that exists on both arrays. To do this we'll run the filter() method on array A with the question if any item exists on set B and do the same for array B with set A.

This question will be answered with the has() method of Set that returns a boolean if this item exists inside the set. Using the ! (bang operator) we only include the false values.

...
const aFiltered = a.filter(item => !setB.has(fn(item)));
const aFiltered = b.filter(item => !setA.has(fn(item)));
...

Great! The only thing we have to do now is return an array containing both our aFiltered and bFiltered arrays. We can do this easily with the spread operator:

...
return [...aFiltered, ...bFiltered]
...

Then we'll refactor our code a bit to make it cleaner by putting our variables on one line and directly returning the combined array:

const getSymmetricDifference = (a, b, fn) => {
  const setA = new Set(a.map(item => fn(item))), setB = new Set(b.map(item => fn(item)));
  return [...a.filter(item => !setB.has(fn(item))), ...b.filter(item => !setA.has(fn(item)))]
};

That's it! We learned about the Set object, map() and filter() methods and other stuff of JavaScript. Have fun building things!

Make sure to follow me for more tutorials. 🧠

Latest comments (0)