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

В чем разница между Set и массивом?

1.0 Junior🔥 191 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

В чем разница между Set и массивом?

Set и массив — это две разные структуры данных в JavaScript, каждая со своими преимуществами и недостатками. Выбор между ними зависит от конкретной задачи.

Основные различия

1. Уникальность значений

Массив может содержать дубликаты:

const array = [1, 2, 2, 3, 3, 3];
console.log(array.length); // 6

Set хранит только уникальные значения:

const set = new Set([1, 2, 2, 3, 3, 3]);
console.log(set.size); // 3

2. Структура и производительность

Массив:

  • Упорядоченная коллекция элементов
  • Доступ по индексу: O(1)
  • Поиск элемента: O(n)
  • Удаление элемента: O(n)

Set:

  • Коллекция уникальных значений
  • Нет доступа по индексу
  • Проверка наличия: O(1)
  • Удаление элемента: O(1)

3. Использование памяти

// Для проверки наличия элемента

// Массив - неэффективно для больших данных
const array = [1, 2, 3, 4, 5, 100000];
array.includes(99999); // O(n) - проверяет все элементы

// Set - очень быстро
const set = new Set([1, 2, 3, 4, 5, 100000]);
set.has(99999); // O(1) - прямая проверка

Создание

Массив

// Литеральная нотация
const array1 = [1, 2, 3];

// Конструктор Array
const array2 = new Array(1, 2, 3);

// Из другого итерируемого объекта
const array3 = Array.from('hello'); // ['h', 'e', 'l', 'l', 'o']

Set

// Конструктор Set (принимает итерируемый объект)
const set1 = new Set([1, 2, 2, 3]);
console.log(set1.size); // 3

// Пустой Set
const set2 = new Set();

// Из строки
const set3 = new Set('hello');
console.log(set3); // Set(4) { 'h', 'e', 'l', 'o' }

Методы и свойства

Массив

const array = [1, 2, 3];

// Свойства
array.length; // 3

// Методы
array.push(4);           // Добавить в конец
array.pop();             // Удалить последний
array.shift();           // Удалить первый
array.unshift(0);        // Добавить в начало
array.includes(2);       // Проверить наличие
array.indexOf(2);        // Найти индекс
array.filter(x => x > 1); // Отфильтровать
array.map(x => x * 2);   // Преобразовать

Set

const set = new Set([1, 2, 3]);

// Свойства
set.size; // 3

// Методы
set.add(4);              // Добавить элемент
set.delete(2);           // Удалить элемент
set.has(2);              // Проверить наличие
set.clear();             // Очистить Set
set.values();            // Итератор по значениям
set.keys();              // Итератор по ключам (= values в Set)
set.entries();           // Итератор по парам [value, value]
set.forEach(callback);   // Итерация

// Преобразование в массив
Array.from(set);         // [1, 2, 3]
[...set];                // [1, 2, 3]

Сравнение производительности

Проверка наличия элемента

// Генерируем большой массив
const largeArray = Array.from({length: 100000}, (_, i) => i);
const largeSet = new Set(largeArray);

// Проверка в массиве - медленно
console.time('Array.includes');
for (let i = 0; i < 1000; i++) {
  largeArray.includes(99000); // O(n)
}
console.timeEnd('Array.includes'); // ~100ms

// Проверка в Set - быстро
console.time('Set.has');
for (let i = 0; i < 1000; i++) {
  largeSet.has(99000); // O(1)
}
console.timeEnd('Set.has'); // ~1ms

Практические примеры

1. Удаление дубликатов из массива

// Способ 1: использование Set
const array = [1, 2, 2, 3, 3, 3, 4];
const unique = [...new Set(array)];
console.log(unique); // [1, 2, 3, 4]

// Способ 2: фильтрация
const unique2 = array.filter((v, i) => array.indexOf(v) === i);

2. Пересечение двух массивов

const array1 = [1, 2, 3, 4];
const array2 = [3, 4, 5, 6];

const set1 = new Set(array1);
const intersection = array2.filter(x => set1.has(x));
console.log(intersection); // [3, 4]

3. Проверка наличия ID пользователя в списке запрещенных

// Плохо: O(n) для каждой проверки
const bannedUserIds = [123, 456, 789, ...];
function isUserBanned(userId) {
  return bannedUserIds.includes(userId); // медленно
}

// Хорошо: O(1) для каждой проверки
const bannedUserSet = new Set([123, 456, 789, ...]);
function isUserBanned(userId) {
  return bannedUserSet.has(userId); // быстро
}

4. Отслеживание посещённых элементов

function findPath(graph, start, end) {
  const visited = new Set(); // O(1) проверка
  
  function dfs(node) {
    if (visited.has(node)) return false;
    if (node === end) return true;
    
    visited.add(node);
    for (const neighbor of graph[node]) {
      if (dfs(neighbor)) return true;
    }
    
    return false;
  }
  
  return dfs(start);
}

5. Кэширование результатов

const cache = new Set();

function expensiveOperation(value) {
  if (cache.has(value)) {
    console.log('Из кэша');
    return value;
  }
  
  console.log('Вычисляем...');
  cache.add(value);
  return value * 2;
}

expensiveOperation(5); // Вычисляем...
expensiveOperation(5); // Из кэша

Итерация

Массив

const array = [1, 2, 3];

// for-of
for (const value of array) {
  console.log(value);
}

// forEach
array.forEach((value, index) => {
  console.log(index, value);
});

// map, filter, reduce
array.map(x => x * 2);

Set

const set = new Set([1, 2, 3]);

// for-of
for (const value of set) {
  console.log(value);
}

// forEach
set.forEach((value) => {
  console.log(value);
});

// Преобразуем в массив и используем методы массива
[...set].map(x => x * 2);

Когда использовать Set?

  • Проверка наличия элемента в большом наборе данных
  • Удаление дубликатов
  • Реализация алгоритмов графов (посещённые узлы)
  • Кэширование уникальных значений
  • Работа с уникальными ID
  • Когда не нужен доступ по индексу

Когда использовать массив?

  • Нужна упорядоченность и доступ по индексу
  • Часто нужны методы преобразования (map, filter, reduce)
  • Нужны дубликаты
  • Нужна совместимость с JSON (JSON.stringify)
  • Проще в использовании для простых случаев

Гибридный подход

// Используем Set для быстрой проверки
const userIds = [1, 2, 3, 4, 5];
const userSet = new Set(userIds);

function processUsers(ids) {
  const results = [];
  
  for (const id of ids) {
    if (userSet.has(id)) {
      results.push(getUserData(id)); // O(1) проверка
    }
  }
  
  return results;
}

Резюме

ХарактеристикаМассивSet
УникальностьМожет быть дубликатыТолько уникальные
Доступ по индексуДа O(1)Нет
Проверка наличияМедленно O(n)Быстро O(1)
УдалениеМедленно O(n)Быстро O(1)
Методы преобразованияМного (map, filter)Мало
JSON.stringifyРаботаетНужна конвертация

Выводы:

  • Set лучше для проверки наличия и уникальности
  • Массив лучше для упорядоченности и преобразований
  • Часто используют оба вместе для оптимальной производительности
В чем разница между Set и массивом? | PrepBro