Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Для чего нужен Set в JavaScript
Set — это встроенный объект в JavaScript, который представляет собой коллекцию уникальных значений. В отличие от массива, Set автоматически исключает дубликаты и предоставляет оптимизированные методы для работы с уникальными значениями. Set был введен в ES2015 (ES6) и стал незаменимым инструментом для многих задач в современной разработке.
Основные особенности Set
1. Уникальные значения
Set автоматически исключает дубликаты:
const numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4];
// Неправильно — массив содержит дубликаты
console.log(numbers.length); // 10
// Правильно — Set содержит только уникальные значения
const uniqueNumbers = new Set(numbers);
console.log(uniqueNumbers.size); // 4
2. Создание и инициализация
// Пустой Set
const emptySet = new Set();
// Set с начальными значениями
const colors = new Set(['red', 'green', 'blue']);
console.log(colors.size); // 3
// Set из строки (строка — это итерируемая коллекция символов)
const chars = new Set('hello');
console.log(chars); // Set { 'h', 'e', 'l', 'o' }
3. Основные методы
const set = new Set();
// add() — добавляет значение
set.add(1);
set.add(2);
set.add(2); // Не добавится, так как 2 уже в Set
console.log(set.size); // 2
// has() — проверяет наличие значения
console.log(set.has(1)); // true
console.log(set.has(3)); // false
// delete() — удаляет значение
set.delete(1);
console.log(set.has(1)); // false
// clear() — удаляет все значения
set.clear();
console.log(set.size); // 0
Сравнение с массивом
const array = [1, 2, 2, 3];
const set = new Set(array);
// Проверка наличия элемента
// Массив O(n) — медленно
console.log(array.includes(2)); // true
// Set O(1) — быстро
console.log(set.has(2)); // true
// Размер
console.log(array.length); // 4
console.log(set.size); // 3
// Дубликаты
array.push(2);
set.add(2); // Не добавится
Практические применения
1. Удаление дубликатов
// Наивный подход с массивом
function removeDuplicatesArray(arr) {
return arr.filter((item, index) => arr.indexOf(item) === index);
}
// Быстрый подход с Set
function removeDuplicatesSet(arr) {
return Array.from(new Set(arr));
}
// Или еще компактнее
const removeDuplicates = (arr) => [...new Set(arr)];
const numbers = [1, 2, 2, 3, 3, 3, 4];
console.log(removeDuplicates(numbers)); // [1, 2, 3, 4]
2. Отслеживание посещённых элементов
// Граф: найти все вершины, достижимые из стартовой
function getReachableNodes(graph, start) {
const visited = new Set();
const queue = [start];
while (queue.length > 0) {
const node = queue.shift();
if (visited.has(node)) continue;
visited.add(node);
for (const neighbor of graph[node] || []) {
if (!visited.has(neighbor)) {
queue.push(neighbor);
}
}
}
return visited;
}
const graph = {
'A': ['B', 'C'],
'B': ['D'],
'C': ['E'],
'D': [],
'E': []
};
console.log(getReachableNodes(graph, 'A')); // Set { 'A', 'B', 'C', 'D', 'E' }
3. Отслеживание активных пользователей
class ChatRoom {
constructor() {
this.activeUsers = new Set();
}
userJoins(userId) {
this.activeUsers.add(userId);
console.log(`User ${userId} joined. Active users: ${this.activeUsers.size}`);
}
userLeaves(userId) {
this.activeUsers.delete(userId);
console.log(`User ${userId} left. Active users: ${this.activeUsers.size}`);
}
isUserActive(userId) {
return this.activeUsers.has(userId);
}
getActiveUsers() {
return Array.from(this.activeUsers);
}
}
const room = new ChatRoom();
room.userJoins('alice');
room.userJoins('bob');
room.userJoins('alice'); // Не добавится второй раз
console.log(room.isUserActive('alice')); // true
console.log(room.getActiveUsers()); // ['alice', 'bob']
4. Проверка наличия элементов в списке
// Фильтрация: оставить только элементы, которые есть в whitelist
const whitelist = new Set(['apple', 'banana', 'orange']);
const fruits = ['apple', 'grape', 'banana', 'kiwi'];
const filtered = fruits.filter(fruit => whitelist.has(fruit));
console.log(filtered); // ['apple', 'banana']
// Наивный подход был бы медленнее
const whitelistArray = ['apple', 'banana', 'orange'];
const filteredSlow = fruits.filter(fruit => whitelistArray.includes(fruit));
5. Нахождение пересечения и объединения
// Пересечение (общие элементы)
function intersection(setA, setB) {
return new Set([...setA].filter(x => setB.has(x)));
}
// Объединение (все элементы)
function union(setA, setB) {
return new Set([...setA, ...setB]);
}
// Разность (элементы из A, которых нет в B)
function difference(setA, setB) {
return new Set([...setA].filter(x => !setB.has(x)));
}
const set1 = new Set([1, 2, 3, 4]);
const set2 = new Set([3, 4, 5, 6]);
console.log(intersection(set1, set2)); // Set { 3, 4 }
console.log(union(set1, set2)); // Set { 1, 2, 3, 4, 5, 6 }
console.log(difference(set1, set2)); // Set { 1, 2 }
Итерация по Set
const colors = new Set(['red', 'green', 'blue']);
// for...of
for (const color of colors) {
console.log(color);
}
// forEach
colors.forEach((color, colorAgain, theSet) => {
console.log(color);
});
// Конвертирование в массив
const colorArray = Array.from(colors);
const colorArray2 = [...colors]; // Спред оператор
Set с объектами
const user1 = { id: 1, name: 'Alice' };
const user2 = { id: 2, name: 'Bob' };
const user3 = { id: 1, name: 'Alice' }; // Другой объект с тем же содержимым
const users = new Set();
users.add(user1);
users.add(user2);
users.add(user3); // Добавится! Это другой объект
console.log(users.size); // 3
// Set проверяет идентичность (===), не равенство
console.log(user1 === user3); // false
console.log(users.has(user1)); // true
console.log(users.has(user3)); // false
Производительность
// Измерение производительности
const largeArray = Array.from({ length: 100000 }, (_, i) => i);
const duplicateArray = [...largeArray, ...largeArray];
// Массив: медленно O(n²) для filter + indexOf
console.time('array');
const unique1 = duplicateArray.filter(
(item, index) => duplicateArray.indexOf(item) === index
);
console.timeEnd('array'); // ~1000ms
// Set: быстро O(n)
console.time('set');
const unique2 = Array.from(new Set(duplicateArray));
console.timeEnd('set'); // ~5ms
WeakSet
Для объектов можно использовать WeakSet — это аналог Set, но со слабыми ссылками (garbage collection):
const wset = new WeakSet();
let obj = { id: 1 };
wset.add(obj);
console.log(wset.has(obj)); // true
obj = null; // Объект удаляется из памяти и автоматически из WeakSet
Итоги
- Set хранит уникальные значения и автоматически исключает дубликаты
- has() работает за O(1) — намного быстрее, чем includes() в массиве
- Идеален для удаления дубликатов, отслеживания состояния, проверки наличия
- Сложнее с объектами — проверяет идентичность, а не равенство
- WeakSet для объектов с автоматической очисткой при garbage collection