Everything you need to know about JavaScript Set
Tags: javascript, beginners, webdev, codenewbie
Published: 2020-09-26 15:21:09

*If you like what I write, you may want to [subscribe to my newsletter](https://blog.greenroots.info/). Feel free to [@ me on twitter](https://twitter.com/tapasadhikary) for any discussion.*

<hr />

JavaScript `objects` and `arrays` are the most used data structures act as collections of data. Until `ES6` there were limited options with developers. But with ES6 we have got two new flexible and easy to use data structures, `Map` and `Set`.

In this article, we will learn about `Set` and we are going to make some salad(🥗) too!

# Set
A `Set` is a collection of `unique`(distinct) elements where each of the elements can be of any type. The `Set` is also an ordered collection of elements. It means the retrieval order of the elements will be the same as that of the insertion order.

> The JavaScript Set behaves the same way as the mathematical set.

Create a `Set`,

```js
const set = new Set();
console.log(set);
```
Output,

```shell
Set(0) {}
```
Initialize a `Set` and create,

```js
const fruteSet = new Set(['🍉', '🍎', '🍈', '🍏']);
console.log(fruteSet);
```
Output,

```shell
Set(4) {"🍉", "🍎", "🍈", "🍏"}
```

## Set methods - Let's make some Salad 🥗!
`Set` has methods to add an element to it, delete elements from it, check if an element exists in it, and to clear it completely. Let us see it by making some salad!

### Add vegetables
Use the `add(element)` method to add an element to the `Set`.

```js
// Create a set - saladSet
const saladSet = new Set();

// Add some vegetables to it
saladSet.add('🍅'); // tomato
saladSet.add('🥑'); // avacado
saladSet.add('🥕'); // carrot
saladSet.add('🥒'); // cucumber

console.log(saladSet);
```
Alright, we have added the vegetables. The output so far,

```shell
Set(4) {"🍅", "🥑", "🥕", "🥒"}
```
### Add another Cucumber - Can we?
I love cucumber! How about adding one more of it. Can I? Oh no, I can't. The `Set` is a collection of `unique` elements.

```js
saladSet.add('🥒');
console.log(saladSet);
```
Output is still as before, nothing got added to the `saladSet`.

```shell
Set(4) {"🍅", "🥑", "🥕", "🥒"}
```
### Does it have a Carrot(🥕) or a Broccoli(🥦)?
Use the `has(element)` method to search an element in a `Set`.

```js
// The salad has a 🥕, so returns true
console.log('Does the Salad has Carrot?', saladSet.has('🥕'));

// The salad doesn't have a 🥦, so returns false
console.log('Does the Salad has Broccoli?', saladSet.has('🥦'));
```
### Lets remove the Avacado(🥑)
User the `delete(element)` method to remove an element from a `Set`.

```js
saladSet.delete('🥑');
console.log('I do not like 🥑, remove from the salad:', saladSet);
```
Now our salad set is,

```shell
I do not like 🥑, remove from the salad: Set(3) {"🍅", "🥕", "🥒"}
```
### Let's clean up, finish the salad!
Use the `clear()` method to remove all the elements from a `Set`.

```js
saladSet.clear();
console.log('Finished it:', saladSet);
```
Output,
```shell
Finished it: Set(0) {}
```
## Iteration with Set
The `Set` has a method called, `values()` which returns a `SetIterator` to get all the values.

```js
// Create a Set
const houseNos = new Set([360, 567, 101]);

// Get the SetIterator using the `values()` method
console.log(houseNos.values());
```
Output,

```shell
SetIterator {360, 567, 101}
```
We can use `forEach` or `for-of` loop on this to retrieve the values.

> Interesting fact:  JavaScript emphasizes to make `Set` compatible with `Map`. That's why we find two `Set` methods, `keys()` and `entries()` like Map.

As `Set` doesn't have a key, the `keys()` method returns a SetIterator to retrieve values.

```js
console.log(houseNos.keys());
```
Output,

```shell
SetIterator {360, 567, 101}
```
Try `entries()` now. For `Map` it returns the iterator to retrieve key-value pairs. There is no key for the Set. Hence the `entries()` method returns a SetIterator to retrieve the value-value pairs.

```js
console.log(houseNos.entries());
```
Output,

```shell
SetIterator {360 => 360, 567 => 567, 101 => 101}
```

### Let's Enumerate
We can enumerate over a Set using `forEach` and `for-of` loop.

```js
houseNos.forEach((value) => {
   console.log(value);
});
```
Output,

```shell
360
567
101
```
With `for-of`,

```js
for(const value of houseNos) {
   console.log(value);
 }
```

# Set and object
A `Set` can have elements of any type, even objects.

```js
// Create a person object
const person = {
   'name': 'Alex',
   'age': 32
 };

// Let us create a set and add the object to it
const pSet = new Set();
pSet.add(person);
console.log(pSet);
```
Output,

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1600611933686/0zm-tUUHv.png?border=1,CCCCCC)

No surprise. The Set contains one element that is an object. Let us now, change a property of the object and add it to the set again.

```js
// Change the name of the person
person.name = 'Bob';

// Add the person object to the set again
pSet.add(person);
console.log(pSet);
```
What do you think about the output? Two `person` objects or the one? Here is the output,

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1600612127767/1toG2q67s.png?border=1,CCCCCC)

`Set` is the collection of unique elements. By changing the property of the object, we haven't changed the object itself. Hence `Set` will not allow duplicate elements.

# Set and Array
An array, like a Set, allows adding and removing elements to it. But Set is different than array and it is not meant to replace array. Using `Set` as an add-on to array actually give more muscles.

The major difference between an array and Set is, array allows duplicate elements where Set is for distinct elements. Some of the Set operations(delete) are also faster than array operations(shift, splice).

> The `Set` data structure is not a replacement of the `array`. `Set` along with array can solve interesting problems.

## Convert Set to an array
In many situations, you may want to convert a Set to an array. In fact, it is very easy!

```js
const arr = [...houseNos];
console.log(arr);
```
Output,

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1600611602568/HCDWAT4B8.png?border=1,CCCCCC)

## Unique values from an array using Set
The most common usage of the Set data structure is to get unique values from an array.

```js
// Create a mixedFruit array with few duplicate fruits
const mixedFruit = ['🍉', '🍎', '🍉', '🍈', '🍏', '🍎', '🍈',];

// Pass the array to create a set of unique fruits
const mixedFruitSet = new Set(mixedFruit);

console.log(mixedFruitSet);
```
Output,

```shell
Set(4) {"🍉", "🍎", "🍈", "🍏"}
```
# Set Operations
It is very easy to perform the basic set operations like, `union`, `intersection`, `diference`, `superset`, `subset` etc with `Set` and array together. Let us take these two sets to perform these oprtations,

```js
const first = new Set([1, 2, 3]);
const second = new Set([3, 4, 5]);
```

## Union

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/d3zdfhsfdmr8sjxoiih5.png)

> `Union` of the sets A and B, denoted A ∪ B, is the set of all items that is a member of A, or B, or both. For example. the union of {1, 2, 3} and {3, 4, 5} is the set {1, 2, 3, 4, 5}.

```js
// Union
const union = new Set([...first, ...second]);
console.log('Union:', union);
```
Output,

```shell
Union: Set(5) {1, 2, 3, 4, 5}
```
## Intersection

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sm3u6u4vcjitz1psxpel.png)

> `Intersection` of the sets A and B, denoted A ∩ B, is the set of all objects that are members of both A and B. For example, the intersection of {1, 2, 3} and {3, 4, 5} is the set {3}.

```js
// Intersection
const intersection = new Set([...first].filter(elem => second.has(elem)));
console.log('Intersection:', intersection);
```
Output,

```shell
Intersection: Set(1) {3}
```

## Difference

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1600927884862/QeZUWRmn1.png)

> `Set difference` of U and A, denoted U \ A, is the set of all members of U that are not members of A. The set difference {1, 2, 3} \ {3, 4, 5} is {1, 2}, while conversely, the set difference {3, 4, 5} \ {1, 2, 3} is {4, 5}.

```js
// Difference
const difference = new Set([...first].filter(elem => !second.has(elem)));
```
Output,

```shell
Difference: Set(2) {1, 2}
```

## Superset 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fx3vx9o9n7nla62kz52s.png)

> A set A is a subset of a set B if all elements of A are also elements of B; B is then a superset of A.

```js
// Is a superset?
const isSuperset = (set, subset) => {
  for (let elem of subset) {
     if (!set.has(elem)) {
         return false;
     }
  }
  return true;
}
console.log('Is Superset?', isSuperset(first, second));
```
Output,

```shell
Is Superset? false
```
Here is some more information about `Set` vs `Array`:

{% twitter 1309042391043788803 %}

# Conclusion
`Set` is a great data structure to use as an add-on with JavaScript arrays. It doesn't have a huge advantage over array though. Use it when you need to maintain a distinct set of data to perform set operations like, `union`, `intersection`, `difference` etc.

Here is the GitHub repository to find all the source code used in this article(and in the [previous article on Map](https://dev.to/atapas/how-to-use-javascript-collection-with-map-1hm0)). If you like, please show your support by giving it a star(🌟).

{% github atapas/js-collections-map-set %}

Know more about the `Set` data structure from here,
- [Set from MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)

You may also like,
- [How to use JavaScript Collection with Map](https://dev.to/atapas/how-to-use-javascript-collection-with-map-1hm0)


<hr />
If it was useful to you, please Like/Share so that, it reaches others as well. You can read my other articles from the [GreenRoots Blog](https://blog.greenroots.info/). 

Feel free to @ me or follow me on twitter [@tapasadhikary](https://twitter.com/tapasadhikary).