andreusjh99 (Jing Heng)

Hello there! Welcome to my blog.

Sets in JavaScript

  • pencil11 Dec 2021
  • clock6 min read
descriptionExplanation of sets, using sets, and comparing 2 sets in JavaScript

What is a Set?

Set is a new type introduced in ES6 (ECMAScript 2015 - a standard for scripting languages including JavaScript). A set is a collection of unique values of any type — each value can only appear once in a set. A JavaScript set behaves similarly to a Python Set.

Values in a set are:

  • unordered — values in a set do not come in a particular order
  • mutable — you can change the values in a set

Sets in JavaScript

To create a new empty JavaScript set:

const mySet = new Set();

To add values into the set:

mySet.add(1); // { 1 }
mySet.add(2); // { 1, 2 }
mySet.add(3); // { 1, 2, 3 }

mySet.add(2); // { 1, 2, 3 } - 2 already exists in the set

To remove values from a set:

mySet.delete(3); // { 1, 2 }

mySet.clear(); // delete all elements from the set

You can also create a set from an array:

const myArray = [1, 2, 3, 4, 2, 3];
const mySet = new Set(myArray); // { 1, 2, 3, 4 }

Note that duplicate values are removed when the set is created.

To check if a value exists in a set:

const myArray = [1, 2, 3, 4, 2, 3];
const mySet = new Set(myArray); // { 1, 2, 3, 4 }

mySet.has(1); // true
mySet.has(5); // false

Set.has() has a time complexity of O($1$), which makes it more efficient than includes() of JavaScript arrays that has a time complexity of O($n$).

Comparing 2 sets

Like other JavaScript objects, two sets cannot be compared using the equality operators (== or ===) as they are used for value equality, not object equality.

To check if 2 sets are equal, there are 2 steps:

  • check if the size of both sets are the same
  • check that every element of set A exists in set B.

Note that, either step alone is insufficient. If every element of set A exists in set B but their sizes are not the same, this indicates that set B has elements that set A does not have.

In other words, to check if 2 sets are equal:

const match = setA.length == setB.length 
    && [...setA].every(value => setB.has(value));

In the code snippet above, [...setA] creates an auxiliary array for every() to be used.

Use case

When will you use a set? A set is useful for situations where you want to deal with collections of objects without caring about duplicates and order.

An analogy: you have 2 baskets of fruits. You want to know if both baskets contain the same types of fruits (apples, oranges, etc.). You don’t care about how many of each type of fruit there is, and you certainly don’t care about the order the fruits are being put into the basket.

Assuming these values are stored in arrays:

const basket1 = [1, 2, 3, 2, 3, 2, 3, 3, 1, 1];
const basket2 = [1, 2, 3, 3, 2, 1, 3, 2];

The straightforward thing to do is to first go through each array to get the unique values from each, then compare the resulting unique values.

With arrays:

// get distinct elements from the arrays
let basket1f = basket1.filter((el, i, a) => {return i == a.indexOf(el)}); // [1, 2, 3]
let basket2f = basket2.filter((el, i, a) => {return i == a.indexOf(el)}); // [1, 2, 3]

// compare the resulting distinct elements
const match = basket1f.length == basket2f.length 
    && basket1f.every(value => basket2f.includes(value)); // O(n**2)

This method has a time complexity of O($n^2$). This is because every() has complexity O($n$), and for each iteration, includes() of complexity O($n$) is called.

Using sets:

// get distinct elements from the arrays
let set1 = new Set(basket1); // {1, 2, 3}
let set2 = new Set(basket2); // {1, 2, 3}

const match = set1.length == set2.length 
    && [...set1].every(value => set2.has(value)); // O(n)

This method has a time complexity of O($n$), because has() has a complexity of O($1$). Moreover, the code is more readable.

Conclusion

  • Set is a collection of unique values of any type.
  • It is useful for dealing with objects when duplicates and order are not important due to its time complexity advantages over arrays.

Author: Chia Jing Heng (andreusjh99)