Post

Filter Arrays for Unique Values

The Problem

Ever needed to remove all the duplicates from an Array in JavaScript, or in other words, had to filter an array for all its unique values? Well, there’s a hard way, an easy way, and an elegant way. I’m going to talk about the hard way first, but feel free to skip to the easy way or the elegant way if you want.

Filtering things can be quite rewarding. Photo by Thomas Martinsen on Unsplash. Filtering things can be quite rewarding. Photo by Thomas Martinsen on Unsplash.

The Hard Way

The hard way of doing this would be to set up two loops. While stepping through the first Array - let’s call that firstArray with the first loop, you’d have to compare each entry in the array to another Array - let’s call this one uniqueValues. You’ll have to set uniqueValues to the first value in firstArray, so there’s something to compare. And then you’ll have to iterate over the second loop to check and add the value if it’s not there yet. Depending on how you set up the loops, there could be an additional problem: the loop will keep going, the computer will keep checking and keep on adding any mismatches to uniqueValues. You might have to use a boolean, let’s say, valueMatched, to keep track of whether you actually already found that value in uniqueValues.

There’s more than one way of doing this, but here’s an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// assuming you have a firstArray and you've declared an empty uniqueValues

uniqueValues.push(firstArray[0]);

firstArray.forEach(value => {
  // set up a boolean to test whether there has
  // been a match already

  let valueMatched = false;

  // iterate over the second array
  uniqueValues.forEach(uniqueValue => {
    if (uniqueValue === value ) {
      valueMatched = true;
    }
  })

  if (!valueMatched) { // this value is unique,
    // so add it to uniqueValues
    uniqueValues.push(value)
  }
})

By the way, that forEach used on uniqueValues will keep getting longer as you push more unique values into the array.

The Easy Way

The easy way, since 2016, would be to let .includes() do the hard work for you, essentially taking the place of that second loop. In this case, too, you wouldn’t have to set an initial value for uniqueValues, since includes() will simply return false for an empty array.

1
2
3
4
5
6
7
// assuming you have a firstArray and you've declared an empty uniqueArray

firstArray.forEach(value => {
  if (!uniqueValues.includes(value)) {
    uniqueValues.push(value)
  }
})

The Elegant Way

The elegant way would be to convert the Array to a Set (and then switching it back to an array with a spread operator):

1
2
const newSet = new Set(arr);
const newArr = [...newSet];

Sets can only hold unique values, so the hard work is being done for you. Magic!

Thanks

I learned about this use of Sets while doing a Frontend Masters course on interviewing taught by Jem Young. One of the benefits of living in Minneapolis is that I can attend some of the Frontend Masters courses in person - for free! They’re a great company with lots of great content - you should check them out.

This post is licensed under CC BY 4.0 by the author.