Объект Set в JS
В этой статье вы познакомитесь с еще одним особым видом колеции в JavaScript — объектом Set.
В предыдущей статье мы уже обсуждали структуры данных, которые появились в JavaScript ES6 — Map и WeakMap.
Set и WeakSet — еще две новые структуры данных из ES6.
Объект Set (множество) похож на массив, который позволяет хранить несколько элементов, таких как числа, строки, объекты и т.д. Однако, в отличие от массива, в множестве не может быть одинаковых значений.
Создание множества
Для создания множества используется конструктор new Set()
. Например:
// создаем множество
const set1 = new Set(); // пустое множество
console.log(set1); // Вывод: Set {}
// множество с разными типами данных
const set2 = new Set([1, 'привет', {count : true}]);
console.log(set2); // Вывод: Set {1, "привет", {count: true}}
Создать Set с повторяющимися значениями, не получится. Все дубликаты будут исключены.
// множество с повторяющимися значениями
const set3 = new Set([1, 1, 2, 2]);
console.log(set3); // Вывод: Set {1, 2}
Доступ к элементам множества
Для доступа к элементам множества используют метод values()
.
const set1 = new Set([1, 2, 3]);
// получаем элементы множества
console.log(set1.values()); // Вывод: Set Iterator [1, 2, 3]
Чтобы узнать, есть ли определенное значение в множестве, можно использовать метод has()
.
const set1 = new Set([1, 2, 3]);
// проверяем, есть ли определенное значение в множестве
console.log(set1.has(1));
Добавление новых элементов в множество
Для добавления новых элементов в множество используют метод add()
.
const set = new Set([1, 2]);
console.log(set.values());
// добавляем новый элемент
set.add(3);
console.log(set.values());
// пытаемся добавить значение, которое уже есть
// оно не добавляется
set.add(1);
console.log(set.values());
Вывод
Set Iterator [1, 2] Set Iterator [1, 2, 3] Set Iterator [1, 2, 3]
Удаление элементов из множества
Для удаления элементов из множества используют методы delete()
и clear()
.
Метод delete()
удаляет определенный элемент из множества.
const set = new Set([1, 2, 3]);
console.log(set.values()); // Вывод: Set Iterator [1, 2, 3]
// удаляем определенный элемент
set.delete(2);
console.log(set.values()); // Вывод: Set Iterator [1, 3]
Метод clear()
удаляет все элементыиз множества.
const set = new Set([1, 2, 3]);
console.log(set.values()); // Вывод: Set Iterator [1, 2, 3]
// удаляем все элементы множества
set.clear();
console.log(set.values()); // Вывод: Set Iterator []
Перебор элементов множества
Перебрать элементы множества можно с помощью цикла for...of или метода forEach(). Доступ к элементам осуществляется в том же порядке, в котором происходило добавление элементов.
const set = new Set([1, 2, 3]);
// перебираем элементы множества
for (let i of set) {
console.log(i);
}
Вывод
1 2 3
Объект WeakSet
WeakSet похож на Set. Но в отличие от Set, в котором могут содержаться любые типы данных, в WeakSet можно хранить только объекты.
const weakSet = new WeakSet();
console.log(weakSet); // Вывод: WeakSet {}
let obj = {
message: 'Привет',
sendMessage: true
}
// добавляем объект (элемент) в WeakSet
weakSet.add(obj);
console.log(weakSet); // Вывод: WeakSet {{message: "Привет", sendMessage: true}}
Если вы попытаетесь добавить в WeakSet другие типы данных, кроме объектов, WeakSet сообщит об ошибке.
// пытаемся добавить строку в WeakSet
weakSet.add('Привет');
// получаем ошибку
// TypeError: Attempted to add a non-object key to a WeakSet
console.log(weakSet);
Методы WeakSet
У WeakSet есть следующие методы: add()
, delete()
и has()
.
Разберем эти методы на примерах:
const weakSet = new WeakSet();
console.log(weakSet); // Вывод: WeakSet {}
const obj = {a:1};
// добавляем элемент в WeakSet
weakSet.add(obj);
console.log(weakSet); // Вывод: WeakSet {{a: 1}}
// проверяем наличие элемента в WeakSet
console.log(weakSet.has(obj)); // Вывод: true
// удаляем элемент
weakSet.delete(obj);
console.log(weakSet); // Вывод: WeakSet {}
WeakSet не поддерживает перебор
В отличие от множества, перебрать элементы WeakSet нельзя. Например:
const weakSet = new WeakSet({a:1});
// пробуем перебрать элементы WeakSet
for (let i of weakSet) {
console.log(i); // возникает ошибка TypeError
}
Математические операции с множествами
В JavaScript у множеств нет встроенных методов для классических математических операций: объединения, пересечения, разности и т.д.
Тем не менее, ничто не мешает нам самим написать программы для этих операций.
Объединение множеств
// функция объединения множеств
// результат должен содержать элементы обоих множеств
function union(a, b) {
let unionSet = new Set(a);
for (let i of b) {
unionSet.add(i);
}
return unionSet
}
// два множества с фруктами
let setA = new Set(['яблоко', 'манго', 'апельсин']);
let setB = new Set(['виноград', 'яблоко', 'банан']);
let result = union(setA, setB);
console.log(result);
Вывод
Set {"яблоко", "манго", "апельсин", "виноград", "банан"}
Пересечение множеств
// функция пересечения множеств
// результат должен содержать элементы,
// которые есть и в множестве a, и в множестве b
function intersection(setA, setB) {
let intersectionSet = new Set();
for (let i of setB) {
if (setA.has(i)) {
intersectionSet.add(i);
}
}
return intersectionSet;
}
// два множества с фруктами
let setA = new Set(['яблоко', 'манго', 'апельсин']);
let setB = new Set(['виноград', 'яблоко', 'банан']);
let result = intersection(setA, setB);
console.log(result);
Вывод
Set {"яблоко"}
Симметричная разность множеств
// функция симметричной разности множеств
// результат должен содержать элементы множества a,
// которых нет в множестве b
function difference(setA, setB) {
let differenceSet = new Set(setA)
for (let i of setB) {
differenceSet.delete(i)
}
return differenceSet
}
// два множества с фруктами
let setA = new Set(['яблоко', 'манго', 'апельсин']);
let setB = new Set(['виноград', 'яблоко', 'банан']);
let result = difference(setA, setB);
console.log(result);
Вывод
Set {"манго", "апельсин"}
Проверка на подмножество
// функция проверяет, является ли множество b подмножеством a
// возвращает true, если все элементы множества b
// содержатся в множестве a
function subset(setA, setB) {
for (let i of setB) {
if (!setA.has(i)) {
return false
}
}
return true
}
// множества с фруктами
let setA = new Set(['яблоко', 'манго', 'апельсин']);
let setB = new Set(['яблоко', 'апельсин']);
let result = subset(setA, setB);
console.log(result);
Вывод
true