Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Зачем нужна коллекция Set
Set (множество) — это встроенная структура данных в JavaScript, которая хранит уникальные значения. Это мощный инструмент для работы с данными, когда нужно избежать дубликатов и быстро проверить наличие элемента.
Основные характеристики Set
- Уникальность: каждое значение может быть в Set только один раз
- Любые типы: может хранить числа, строки, объекты, функции
- Порядок вставки: элементы сохраняют порядок добавления
- Быстрая проверка: O(1) для проверки наличия элемента
- Динамический размер: можно добавлять и удалять элементы
Создание и базовые операции
// Создание пустого Set
const emptySet = new Set();
// Создание Set с начальными значениями
const numbers = new Set([1, 2, 3, 3, 4, 4]);
console.log(numbers); // Set { 1, 2, 3, 4 }
console.log(numbers.size); // 4
// Добавление элемента
numbers.add(5);
console.log(numbers.size); // 5
// Проверка наличия
console.log(numbers.has(3)); // true
console.log(numbers.has(10)); // false
// Удаление элемента
numbers.delete(3);
console.log(numbers.has(3)); // false
// Очистка всех элементов
numbers.clear();
console.log(numbers.size); // 0
Практические примеры использования
1. Удаление дубликатов из массива
const numbers = [1, 2, 2, 3, 3, 4, 5, 5];
const unique = [...new Set(numbers)];
console.log(unique); // [1, 2, 3, 4, 5]
// Или с использованием Array.from
const unique2 = Array.from(new Set(numbers));
// Удаление дубликатов из строк
const letters = "aabbccdd";
const uniqueLetters = [...new Set(letters)].join('');
console.log(uniqueLetters); // "abcd"
2. Отслеживание посещённых элементов
function findPath(graph, start, end) {
const visited = new Set();
const queue = [start];
const parentMap = new Map();
while (queue.length > 0) {
const current = queue.shift();
if (current === end) {
// Восстанавливаем путь
const path = [];
let node = end;
while (node) {
path.unshift(node);
node = parentMap.get(node);
}
return path;
}
if (!visited.has(current)) {
visited.add(current);
for (const neighbor of graph[current]) {
if (!visited.has(neighbor)) {
queue.push(neighbor);
parentMap.set(neighbor, current);
}
}
}
}
return null;
}
3. Быстрая проверка наличия элемента
// Неэффективно: O(n) для каждой проверки
const allowedRoles = ['admin', 'moderator', 'user'];
if (allowedRoles.includes(userRole)) { }
// Эффективно: O(1) для каждой проверки
const allowedRoles = new Set(['admin', 'moderator', 'user']);
if (allowedRoles.has(userRole)) { }
4. Пересечение и объединение массивов
const array1 = [1, 2, 3, 4];
const array2 = [3, 4, 5, 6];
// Объединение (union)
const union = new Set([...array1, ...array2]);
console.log([...union]); // [1, 2, 3, 4, 5, 6]
// Пересечение (intersection)
const set2 = new Set(array2);
const intersection = new Set(array1.filter(x => set2.has(x)));
console.log([...intersection]); // [3, 4]
// Разность (difference)
const difference = new Set(array1.filter(x => !set2.has(x)));
console.log([...difference]); // [1, 2]
5. Отслеживание активных подписчиков
class EventEmitter {
constructor() {
this.subscribers = new Set();
}
subscribe(callback) {
this.subscribers.add(callback);
// Возвращаем функцию для отписки
return () => this.subscribers.delete(callback);
}
emit(data) {
this.subscribers.forEach(callback => callback(data));
}
}
const emitter = new EventEmitter();
const unsubscribe1 = emitter.subscribe(data => console.log('Listener 1:', data));
const unsubscribe2 = emitter.subscribe(data => console.log('Listener 2:', data));
emitter.emit('Hello'); // Вызовет обоих слушателей
unsubscribe1();
emitter.emit('World'); // Вызовет только второго
Set vs Array
| Операция | Set | Array |
|---|---|---|
| Добавление | O(1) | O(1) amortized |
| Удаление | O(1) | O(n) |
| Поиск | O(1) | O(n) |
| Хранение дубликатов | Нет | Да |
| Сортировка | Нет встроенной | Да, sort() |
| Индексный доступ | Нет | Да |
| Итерация | Да, в порядке вставки | Да, по индексам |
Методы и свойства Set
const set = new Set([1, 2, 3]);
// Проверка размера
console.log(set.size); // 3
// Итерация
for (const value of set) {
console.log(value);
}
// Методы
set.forEach((value, key, setObj) => {
console.log(value);
});
// Получение значений
console.log([...set]); // [1, 2, 3]
// Методы итератора
const iterator = set.values();
console.log(iterator.next()); // { value: 1, done: false }
Set с объектами
const users = new Set();
const user1 = { id: 1, name: 'Alice' };
const user2 = { id: 2, name: 'Bob' };
users.add(user1);
users.add(user2);
users.add(user1); // Не добавится, так как user1 уже в Set
console.log(users.size); // 2
console.log(users.has(user1)); // true
// Важно: Set сравнивает по ссылке, не по значению
const user1Copy = { id: 1, name: 'Alice' };
console.log(users.has(user1Copy)); // false, это другой объект
WeakSet для объектов
Для специальных случаев существует WeakSet, который хранит только ссылки на объекты и не препятствует garbage collection:
const weakSet = new WeakSet();
const obj1 = { id: 1 };
const obj2 = { id: 2 };
weakSet.add(obj1);
weakSet.add(obj2);
console.log(weakSet.has(obj1)); // true
// WeakSet полезен для отслеживания объектов без утечек памяти
Вывод
Set — это незаменимая структура данных для многих задач. Её главное преимущество — гарантированная уникальность значений и быстрая проверка наличия элемента O(1). Используйте Set вместо Array когда:
- Нужно избежать дубликатов
- Часто проверяете наличие элемента
- Удаляете элементы часто
- Не нужен индексный доступ