Объект Set
Множества (sets) представляют структуру данных, которая может хранить только уникальные значения. В JavaScript функционал множества опредляет объект Set. Для создания множества применяется конструктор этого объекта:
const mySet = new Set();
Также можно передать в конструктор массив значений, которыми будет инициализировано множество:
const arr = [1, 1, 2, 3, 4, 5, 2, 4];
const numbers = new Set(arr);
// Set(5) {1, 2, 3, 4, 5}
console.log(numbers);
В данном случае в множество передаются данные из массива. Однако поскольку множество может хранить только уникальные значения, то при его создании повторяющиеся значения, которые есть в массиве, удаляются.
Для проверки количества элементов можно использовать свойство size:
const arr = [1, 1, 2, 3, 4, 5, 2, 4];
const numbers = new Set(arr);
// 5
console.log(numbers.size);
Добавление
Для добавления применяется метод add(), его результатом является измененное множество. При этом, поскольку множество хранит только уникальные значения, то добавление элементов, которые уже в нем есть, не имеет смысла:
const numbers = new Set();
numbers.add(1);
numbers.add(3);
numbers.add(5);
// не добавляется
numbers.add(3);
// не добавляется
numbers.add(1);
// Set(3) {1, 3, 5}
console.log(numbers);
Так как метод add возвращает ссылку на это же множество, то мы можем вызывать методы по цепочке:
let numbers = new Set();
numbers.add(1).add(3).add(5);
// Set(3) {1, 3, 5}
console.log(numbers);
Удаление
Для удаления элементов применяется метод delete():
let numbers = new Set();
numbers.add(1).add(3).add(5);
numbers.delete(3);
// Set(2) {1, 5}
console.log(numbers);
Причем данный метод возвращает булевое значение: true — если элемент удален и false — если удаление не произошло (например, когда удаляемого элемента нет в множестве):
let numbers = new Set();
numbers.add(1).add(3).add(5);
let isDeleted = numbers.delete(3);
// true
console.log(isDeleted);
isDeleted = numbers.delete(54);
// false
console.log(isDeleted);
Если необходимо удалить вообще все элементы из множества, то применяется метод clear():
let numbers = new Set();
numbers.add(1).add(3).add(5);
numbers.clear();
// Set(0) {}
console.log(numbers);
Проверка наличия элемента
Если нужно проверить, если ли элемент в множестве, то используется метод has(). Если элемент есть, то метод возвращает true, иначе возвращает false:
let numbers = new Set();
numbers.add(1).add(3).add(5);
// true
console.log(numbers.has(3));
// false
console.log(numbers.has(32));
Перебор множества
Для перебора элементов множества применяется метод forEach():
const arr = [1, 2, 3, 5];
const numbers = new Set(arr);
numbers.forEach(function(value1, value2, set){
console.log(value1);
})
Для совместимости с массивами, которые тоже имеют метод forEach, в данный метод передается функция обратного вызова, которая принимает три параметра. Непосредственно для множества первый и второй параметры представляют текущий перебираемый элемент, а третий параметр — перебираемое множество.
Также для перебора множества можно использовать цикл for...of:
const numbers = new Set([1, 2, 3, 5]);
for(n of numbers){
console.log(n);
}
Получение итератора
Также у объекта Set есть ряд методов, которые возвращают итератор, а точнее объект SetIterator. Это методы values(), keys(), values():
const numbers = new Set([1, 2, 3, 5]);
// SetIterator {1, 2, 3, 5}
console.log(numbers.values());
// SetIterator {1, 2, 3, 5}
console.log(numbers.keys());
// SetIterator {1 => 1, 2 => 2, 3 => 3, 5 => 5}
console.log(numbers.entries());
Соответственно возвращаемый итератор мы можем использовать для получения объектов множества:
const people = new Set(["Tom", "Bob", "Sam"]);
const iterator = people.values();
// {value: "Tom", done: false}
console.log(iterator.next());
// {value: "Bob", done: false}
console.log(iterator.next());
// {value: "Sam", done: false}
console.log(iterator.next());
// {value: undefined, done: true}
console.log(iterator.next());
Удаление из массива повторяющихся элементов
Ограничения объекта Set — хранения уникальных значений позволяет эффективно его применять в ряде операций. Например, удаление из массива повторяющихся элементов:
const peopleArray = ["Tom", "Bob", "Sam", "Alice", "Sam", "Kate", "Tom"];
const peopleSet = new Set(peopleArray);
const newPeopleArray = Array.from(peopleSet);
// ["Tom", "Bob", "Sam", "Alice", "Kate"]
console.log(newPeopleArray);
Здесь для создания нового массива с неповторяющимися элементами применяется функция Array.from(), которая в качестве аргумента получает объект Set.