Ответ
Set — это встроенная в JavaScript коллекция, которая хранит уникальные значения любого типа (примитивы или ссылки на объекты). В Node.js Set часто используется для эффективной работы с уникальными данными, устранения дубликатов и проверки принадлежности.
Основные характеристики:
- Уникальность: Каждое значение может встречаться в
Setтолько один раз. Проверка уникальности использует алгоритм "SameValueZero" (аналогично строгому равенству===, но гдеNaNсчитается равнымNaN). - Порядок: Элементы перебираются в порядке их добавления.
- Производительность: Методы
add,has,deleteработают в среднем за O(1), что делаетSetочень эффективным для проверки наличия элемента.
Базовые операции:
const uniqueTags = new Set();
// Добавление
uniqueTags.add('javascript');
uniqueTags.add('nodejs');
uniqueTags.add('javascript'); // Не добавится, дубликат
console.log(uniqueTags); // Set(2) { 'javascript', 'nodejs' }
// Проверка наличия
console.log(uniqueTags.has('nodejs')); // true
// Удаление
uniqueTags.delete('javascript');
// Размер коллекции
console.log(uniqueTags.size); // 1
// Итерация
for (const tag of uniqueTags) {
console.log(tag); // 'nodejs'
}
// Или преобразование в массив
const tagArray = [...uniqueTags]; // ['nodejs']
Практические примеры использования в Node.js:
- Удаление дубликатов из массива — самый частый случай:
const duplicateIds = [101, 102, 101, 103, 102, 104]; const uniqueIds = [...new Set(duplicateIds)]; console.log(uniqueIds); // [101, 102, 103, 104] -
Кэширование или отслеживание уже обработанных элементов:
// При обработке потока данных (например, из WebSocket) const processedMessageIds = new Set(); socket.on('message', (message) => { if (processedMessageIds.has(message.id)) { return; // Уже обрабатывали, игнорируем } processedMessageIds.add(message.id); // ... логика обработки сообщения }); -
Проверка на допустимые значения:
const validStatuses = new Set(['pending', 'processing', 'shipped', 'delivered']); function updateOrderStatus(newStatus) { if (!validStatuses.has(newStatus)) { throw new Error(`Invalid status: ${newStatus}`); } // ... обновление статуса в БД } -
Построение отношений (объединение, пересечение, разность):
const admins = new Set(['user1@mail.com', 'user2@mail.com']); const activeUsers = new Set(['user2@mail.com', 'user3@mail.com']); // Пользователи, которые являются и админами, и активными const activeAdmins = new Set([...admins].filter(x => activeUsers.has(x))); // Все уникальные пользователи из обоих множеств (объединение) const allUsers = new Set([...admins, ...activeUsers]);
Отличие от массива: Set не имеет индексов и методов типа map или filter (но его легко преобразовать в массив для этого). Его сила — в гарантированной уникальности и быстром поиске.
Отличие от объекта ({}): Set специализирован на хранение коллекции значений, а не пар ключ-значение. Ключами в Set являются сами значения.
Ответ 18+ 🔞
Давай разберемся, что это за зверь такой — Set в JavaScript. Представь себе, что у тебя есть мешок, но не простой, а волшебный: ты пытаешься засунуть в него две одинаковые конфеты, а он одну просто выплевывает. Вот этот мешок — и есть Set. Коллекция, которая хранит только уникальные значения любого типа — хоть строки, хоть числа, хоть ссылки на объекты. В Node.js эта штука просто незаменима, когда нужно быстро проверить, было ли что-то уже, или отфильтровать дубликаты.
Что он из себя представляет, ёпта:
- Уникальность — его конёк: Одно значение — один раз. Точка. Проверяет он это по алгоритму "SameValueZero", это почти как строгое равенство (
===), но с одной хитрой жопой:NaNсчитается равным самому себе. Так что дваNaNв одинSetне запихнёшь — ни хуя себе, да? - Порядок: Элементы перебираются ровно в том порядке, в котором ты их туда закидывал. Не как в обычном объекте, где порядок ключей может быть ебушки-воробушки.
- Скорость — просто пиздец: Методы
add,has,deleteработают в среднем за O(1). Это значит, что проверка, есть ли элемент в коллекции из миллиона записей, происходит почти мгновенно. Доверия ебать ноль к массивам для таких задач после этого.
Базовые операции, чтобы не быть манда с ушами:
const uniqueTags = new Set();
// Добавляем
uniqueTags.add('javascript');
uniqueTags.add('nodejs');
uniqueTags.add('javascript'); // Второй раз не добавится, дубль же!
console.log(uniqueTags); // Set(2) { 'javascript', 'nodejs' }
// Проверяем, есть ли
console.log(uniqueTags.has('nodejs')); // true
// Удаляем
uniqueTags.delete('javascript');
// Смотрим размер
console.log(uniqueTags.size); // 1
// Перебираем
for (const tag of uniqueTags) {
console.log(tag); // 'nodejs'
}
// Или просто превращаем в массив, если надо
const tagArray = [...uniqueTags]; // ['nodejs']
Где это реально пригождается в Node.js (практика, блядь):
- Удаление дубликатов из массива — святое дело:
const duplicateIds = [101, 102, 101, 103, 102, 104]; const uniqueIds = [...new Set(duplicateIds)]; // Всё, дубли накрылись медным тазом console.log(uniqueIds); // [101, 102, 103, 104] -
Кэш или трекер обработанного говна:
// Допустим, обрабатываешь сообщения из сокета const processedMessageIds = new Set(); socket.on('message', (message) => { if (processedMessageIds.has(message.id)) { return; // Уже видел это, иди на хуй, сообщение } processedMessageIds.add(message.id); // ... дальше уже делаешь с ним что нужно }); -
Валидация допустимых значений:
const validStatuses = new Set(['pending', 'processing', 'shipped', 'delivered']); function updateOrderStatus(newStatus) { if (!validStatuses.has(newStatus)) { throw new Error(`Invalid status: ${newStatus}`); // Подсовываешь хуйню — получаешь ошибку } // ... нормально обновляешь статус в базе } -
Работа с множествами (объединение, пересечение):
const admins = new Set(['user1@mail.com', 'user2@mail.com']); const activeUsers = new Set(['user2@mail.com', 'user3@mail.com']); // Кто и админ, и активный (пересечение) const activeAdmins = new Set([...admins].filter(x => activeUsers.has(x))); // Все уникальные юзеры с обоих списков (объединение) const allUsers = new Set([...admins, ...activeUsers]);
Чем он не является:
- Это не массив. У него нет индексов,
mapилиfilterпрямо из коробки. Но его всегда можно разобрать в массив оператором...— и тогда делай с ним что хочешь. - Это не объект
{}. Он заточен под коллекцию значений, а не пар ключ-значение. Ключ здесь — это само значение. Проще, блядь, некуда.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶