If you’ve ever written any Python, you’ve likely come across sets. They’re really useful for creating a data structure where every element is ‘distinct’ (i.e. it has no duplicates).

# A python list, note how it contains a duplicate value
my_arr = ['cow', 'duck', 'horse', 'duck']

# Convert it to a set, which cannot have duplicate values
my_set = set(my_arr)

print(my_set)
# Outputs {'cow', 'duck', 'horse'}

If you want a mathematical definition, from Wolfram Math:

A set is a finite or infinite collection of objects in which order has no significance, and multiplicity is generally also ignored (unlike a list).

So order isn’t important, and you can’t have duplicates.

Using Sets in JavaScript

ES6 introduced sets to JavaScript:

myArray = ['cow', 'duck', 'horse', 'duck'];
mySet = new Set(myArray);

Now we have a set! We can use the in-built methods to add, delete, search etc. These will seem familiar to array methods.

mySet.add('fish'); //mySet now contains ['cow', 'duck', 'horse', 'fish']
mySet.contains('cow'); // true!
mySet.delete(2); //mySet now contains ['cow', 'duck', 'fish'] as we've deleted the 2nd element

A JavaScript set returns an Iterable - that is something you can iterate over! And so to loop, you can use forEach, or let X of Set:

for (let item of mySet) {
    console.log(item);
};

and:

mySet.forEach(function(value) {
  console.log(value);
});

Iterators are handy, and a future blog post will cover iterators and generators!

Be Careful with Equality!

In a set, order is unimportant. The contents of a set are said to be the same if they contain the same elements, but they don’t need to be in the same order. Think of a set as as box that contains a load of ‘things’. Two boxes either contain the same things, or they don’t.

In Python, this equality is observed. For example:

mySet = {'t', 'e', 's'}
anotherSet = {'e', 's', 't'}

print(mySet == anotherSet)
# Outputs True, the order is unimportant and both sets contain the same things

However, in JavaScript it is not:

mySet = new Set('cow', 'duck', 'horse');
mySet2 = new Set('duck', 'horse', 'cow');

console.log(mySet === mySet2);
// Outputs false, uhhh...

JavaScript doesn’t compare equality of sets in the true sense, it compares whether they are the same object (which they aren’t, in the example above).

Bonus: Simply convert an array into a array without duplicates

As a bonus, we can combine the Set() object with ES6’s spread operator (...), and re-populate an array with our new set, complete with only the unique values of our original array. No need for reducers or filters!

myArray = ['cow', 'duck', 'horse', 'duck'];
myDistinctArray = [...new Set(myArray)];

console.log(myDistinctArray);
// Outputs ["cow", "duck", "horse"]

// Or 'in-place':
myArray = [...new Set(myArray)];

Wrap Up

JS sets are useful little utilities. They aren’t as rigourously implemented as Python sets (see the issues with comparison), but for tasks such as removing duplicates they can definitely become part of your arsenal.