На протяжении большей части моей карьеры программиста мне не хватало этого прекрасного стандартного встроенного объекта коллекции. В основном это было связано с тем, что версия 0.10 узла не поддерживала его. Node продолжал обновляться и представил это еще в версии 0.12. Я никогда не удосужился проверить, реализовано ли это, хотя я широко использую Set в Python.

Что такое набор?

Установить объект позволяет хранить уникальные значения любого типа, примитива или ссылки на объект. Необязательно, чтобы все значения, хранящиеся в наборе, были одного типа. Вы можете перебирать значения в наборе в порядке вставки. Поскольку каждое значение в наборе должно быть уникальным, необходимо проверить равенство значений.

NaN and undefined can be stored in a set. All NaN values are treated as same in a set even though NaN !== NaN

Как это использовать?

Давайте посмотрим, как мы можем создавать новые наборы и использовать некоторые из встроенных методов.

  1. Создание нового набора
Syntax:
new Set([iterable])
If an iterable object is passed, all its elements will be added to the set. If it is not passed or its value is null, an empty set will be created.
Examples:
let mySet  = new Set(); // new empty set
let setArray = new Set([1,2,3,4]);
console.log(setArray);
Set { 1, 2, 3, 4 }
// only unique values can be added to a set
let setArrayUnique = new Set([1,2,3,3,4,4,4]); 
console.log(setArrayUnique);
Set { 1, 2, 3, 4 }
// remove duplicates from array
console.log([...setArrayUnique]);
[ 1, 2, 3, 4 ]
console.log([...new Set([1,2,3,3,3,3,4,4,4,4,5])])
[ 1, 2, 3, 4, 5 ]

2. Использование свойств

Set.prototype.size 
Returns the count of values in the set
Examples:
mySet.size
0
setArray.size
4

3. Встроенные методы

Давайте посмотрим на некоторые встроенные методы и их использование.

Set.prototype.add(value)
Adds the value to the set.
Set.prototype.clear()
Removes all values from the set.
Set.prototype.delete(value)
Remove the element associated with the value. This method returns true if element existed in the set and has been deleted. If the element did not exist in the set it returns false.
Set.prototype.has(value)
Returns true if set has an element which equals value else false.
Examples:
let mySet = new Set();
// adding elements to a Set
mySet.add(1);
mySet.add(2);
mySet.add(3);
mySet.add(1);
console.log(mySet);
Set { 1, 2, 3 }
mySet.delete(2);
true
mySet.delete(5); // 5 does not exist in mySet
false
console.log(mySet);
Set { 1, 3 }
mySet.clear();
console.log(mySet);
Set {}
// creating a new Set
mySet = new Set([{}, {key:{innerKey:1}}, 12]);
let d = {key:{innerKey:1}};
mySet.has(12); // primitive value
true
mySet.has({});
false
mySet.has({key:{innerKey:1}});
false
// Even though while creating mySet `{}` and `{key:{innerKey:1}}` were added they are not being found when looked for via `has()` This is because the Set stores the object references. The empty {} being searched has a different reference than the one stored while creating. Lets add another element to the set
mySet.add(d);
console.log(mySet);
Set { {}, { key: { innerKey: 1 } }, 12, { key: { innerKey: 1 } } }
mySet.has(d);
true
// In this case variable d is added to the set and the same variable is searched for in the set.

4. Зацикливание набора

let mySet = new Set([1,2,3,4]);
for (let item of mySet) {console.log(item);}
1
2
3
4
mySet.forEach(function(value){console.log(value);})
1
2
3
4

5. Основные операции над наборами: подмножество

Операции с базовыми наборами недоступны как встроенные методы. Однако мы можем добавить эти методы в класс Set и использовать их.

subSet:
Given sets A = {1,2,3}, B = {1,2,3,4} A is a subset of B only if each element of A is present in B. 
Representation:  A ⊂ B 
Set.prototype.subSet  = function (setB){
/* if the size of current set (say A) is more then the otherSet (say B) A cannot be a subSet of B */
   if(this.size > setB.size){
      return false;
    } else { 
      for (let el of this){
        if(!setB.has(el)){
          return false;
        } 
      }
      return true;
    }
}
Usage: 
let A = new Set([1,2,3]);
let B = new Set([1,2,3,4]);
let C = new Set([1,3,5]);
A.subSet(B)
true
A.subSet(C)
false

6. Базовая установка: Союз

union:
Given sets A = {1,2,3}, B = {1,2,3,4} A union B is a set which contains all elements of A and B. 
Representation: A U B
Set.prototype.union  = function union(setB) {
    let _union = new Set(this)
    for (let el of setB) {
        _union.add(el)
    }
    return _union
}
Usage:
let A = new Set([1,2,3]);
let B = new Set([1,2,3,4]);
let C = new Set([1,3,5]);
A.union(B)
Set { 1, 2, 3, 4 }
A.union(B).union(C)
Set { 1, 2, 3, 4, 5 }

7. Работа базовой установки: пересечение

intersection:
Given sets A = {1,2,3}, B = {1,2,3,4} A intersection B is a set which contains all elements which are present in both A and B. 
Representation: A n B
Set.prototype.intersection = function intersection(setB) {
    let _intersection = new Set()
    for (let el of setB) {
        if (this.has(el)) {
            _intersection.add(el)
        }
    }
    return _intersection
}
Usage: 
let A = new Set([1,2,3]);
let B = new Set([1,2,3,4]);
let C = new Set([1,3,5]);
A.intersection(B)
Set { 1, 2, 3 }
A.intersection(B).intersection(C)
Set { 1, 3 }

8. Работа базовой установки: симметричная разность.

symmetric difference:
Given sets A = {1,2,3}, B = {1,2,3,4} A symmetric difference B is a set which contains all elements which are present in either A or B but not in both. 
Representation: A △ B
Set.prototype.symmetricDifference = function symmetricDifference( setB) {
    let _difference = new Set(this)
    for (let el of setB) {
        if (_difference.has(el)) {
            _difference.delete(el)
        } else {
            _difference.add(el)
        }
    }
    return _difference
}
Usage: 
let X= new Set([1,2,3,6]);
let Y= new Set([1,2,3,4]);
X.symmetricDifference(Y)
Set { 6, 4 }

9. Работа базовой установки: разница

difference:
Given sets A = {1,2,3}, B = {1,2,3,4} difference between A and B is a set which contains all elements which are present in A but not in B. 
Representation: A - B
Set.prototype.difference = function difference(setB) {
    let _difference = new Set(this)
    for (let el of setB) {
        _difference.delete(el)
    }
    return _difference
}
Usage: 
let X= new Set([1,2,3,6]);
let Y= new Set([1,2,3,4]);
X.difference(Y);
Set { 6 }
X.difference(X);
Set {}
Y.difference(X);
Set { 4 }

Вывод

Set - хороший класс коллекции, который можно использовать для написания более чистого кода.