← Назад к вопросам

Что такое структура данных Set?

2.0 Middle🔥 151 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое структура данных Set (Множество)?

Set (множество) — это встроенная структура данных (коллекция) в JavaScript, представляющая собой неупорядоченную коллекцию уникальных значений. Это означает, что она может хранить только неповторяющиеся элементы — при попытке добавить дубликат он будет проигнорирован. Set был введен в спецификации ECMAScript 2015 (ES6).

Ключевые особенности Set:

  • Уникальность значений: Гарантирует, что каждое значение встречается только один раз. Проверка уникальности использует алгоритм SameValueZero (аналогичен строгому равенству ===, но с особенностью: NaN считается равным NaN, в отличие от ===).
  • Отсутствие индексов: Элементы не имеют ключей или индексов. Доступ к ним осуществляется через методы перебора или проверки наличия.
  • Динамический размер: Коллекция автоматически меняет размер при добавлении или удалении элементов.
  • Итерабельность: Set является итерируемым объектом, поэтому его можно использовать в циклах for...of, преобразовывать в массив с помощью Array.from() или оператора spread (...).

Основные методы и свойства

Создание:

const mySet = new Set(); // Пустой Set
const setFromArray = new Set([1, 2, 3, 2, 1]); // Set(3) { 1, 2, 3 }
const setWithMixedTypes = new Set(['a', 42, true, {name: 'John'}, NaN]);

Основные методы:

  • .add(value) — добавляет значение в множество. Возвращает сам Set, что позволяет делать цепочки вызовов.
    mySet.add('apple');
    mySet.add('banana').add('apple'); // Повторное добавление 'apple' игнорируется
    
  • .has(value) — проверяет наличие значения. Возвращает true или false.
    console.log(mySet.has('banana')); // true
    console.log(mySet.has('grape'));  // false
    
  • .delete(value) — удаляет конкретное значение. Возвращает true, если элемент существовал и был удален.
    mySet.delete('apple');
    
  • .clear() — полностью очищает множество.
    mySet.clear();
    
  • .size (свойство, не метод) — возвращает количество элементов.
    console.log(setFromArray.size); // 3
    

Итерация: Так как Set реализует протокол итерации, доступны несколько способов:

const fruits = new Set(['яблоко', 'апельсин', 'банан']);

// 1. for...of
for (let fruit of fruits) {
    console.log(fruit);
}

// 2. Метод .forEach()
fruits.forEach((value) => console.log(value));

// 3. Преобразование в массив
const fruitArray = [...fruits]; // ['яблоко', 'апельсин', 'банан']
const fruitArray2 = Array.from(fruits);

Практические применения и сравнение с массивом

Set незаменим в задачах, где требуется обеспечить уникальность или быстро проверить существование элемента.

  1. Удаление дубликатов из массива (самое популярное использование):
    const duplicates = [1, 2, 2, 3, 4, 4, 4, 5];
    const uniqueValues = [...new Set(duplicates)]; // [1, 2, 3, 4, 5]
    
    Это намного эффективнее и лаконичнее, чем использование цикла с проверкой через `indexOf` или `includes`.

  1. Проверка принадлежности (быстрый includes):
    Поиск элемента в Set (метод `.has()`) в среднем выполняется за **время, близкое к O(1)**, что делает его значительно **быстрее** метода `.includes()` у массива (который в худшем случае имеет сложность O(n)), особенно на больших объемах данных.

  1. Хранение уникальных значений сложных типов:
    Set хранит ссылки на объекты, поэтому один и тот же объект по ссылке не добавится дважды. Однако два разных объекта с одинаковым содержимым будут считаться разными.
```javascript
const objSet = new Set();
const user = {id: 1};
objSet.add(user);
objSet.add(user); // Не добавится
objSet.add({id: 1}); // Добавится, это новый объект с новой ссылкой
```

4. Математические операции с множествами: ```javascript // Объединение const union = new Set([...setA, ...setB]);

// Пересечение
const intersection = new Set([...setA].filter(x => setB.has(x)));

// Разность (A \ B)
const difference = new Set([...setA].filter(x => !setB.has(x)));
```

WeakSet: специальная форма Set

WeakSet — это особая разновидность Set, которая:

  • Может содержать только объекты (не примитивы).
  • Не препятствует сборке мусора. Если объект, хранящийся в WeakSet, больше нигде не используется, он будет автоматически удален из памяти даже без явного удаления из WeakSet.
  • Не является итерируемым — у него нет методов для перебора (keys(), values(), entries()), свойства .size или метода .clear().
  • Имеет только три метода: .add(), .has(), .delete().

Область применения WeakSet — хранение дополнительных ("внутренних") метаданных объектов без риска утечек памяти (например, для отслеживания обработанных элементов).

Итог

Set — это высокопроизводительная и удобная структура данных для работы с коллекцией уникальных значений. Его основная сила — быстрая проверка наличия элемента и автоматическое устранение дубликатов. В современной фронтенд-разработке Set часто используется для оптимизации операций с данными (фильтрация, проверка уникальности) и является важной частью арсенала разработчика рядом с массивами и объектами (Map).

Что такое структура данных Set? | PrepBro