Удаление дубликатов в массиве JavaScript: лучшие способы и примеры
-
Дубликаты в массивах мешают при обработке данных в JavaScript. Они появляются при сборе информации из API или пользовательского ввода. Удаление повторов упрощает код и ускоряет работу приложений.
В этой статье разберем основные методы удаления дубликатов. Покажем примеры для простых массивов и объектов. Вы узнаете, как выбрать подходящий подход для вашей задачи.
Итеративный подход к удалению дубликатов
Итеративный метод подразумевает проход по массиву с проверкой каждого элемента на наличие в результирующем списке. Это базовый способ, который работает без современных фич JavaScript. Он понятен новичкам и не зависит от окружения.
Рассмотрим массив чисел [1, 1, 2, 3, 4, 5, 4, 1]. При первом проходе добавляем 1 в новый массив. При втором встречаем 1 снова - пропускаем. В итоге получаем [1, 2, 3, 4, 5]. Такой подход прост, но O(n²) по времени из-за includes().
Вот базовая реализация:
function removeDuplicates(arr) { const uniqueArr = []; for (let i = 0; i < arr.length; i++) { if (!uniqueArr.includes(arr[i])) { uniqueArr.push(arr[i]); } } return uniqueArr; } console.log(removeDuplicates([1, 1, 2, 3, 4, 5, 4, 1])); // [1, 2, 3, 4, 5]- Плюсы: Легко понять, работает везде.
- Минусы: Медленно на больших массивах из-за includes().
- Подходит для обучения или старых браузеров.
Самый быстрый способ: Set в JavaScript
Set - это встроенный объект, который хранит только уникальные значения. Конструктор new Set(arr) автоматически удаляет дубликаты. Затем преобразуем обратно в массив через spread-оператор […new Set(arr)].
Это решение работает за O(n) и является самым быстрым. Пример: из [‘a’, ‘b’, ‘a’, ‘c’, ‘b’] получаем [‘a’, ‘b’, ‘c’]. Set не меняет исходный массив - всегда возвращает новый.
Код минималистичен:
function removeDuplicates(arr) { return [...new Set(arr)]; } console.log(removeDuplicates([1, 2, 2, 3, 4, 4, 5])); // [1, 2, 3, 4, 5] console.log(removeDuplicates(['a', 'b', 'a', 'c', 'b'])); // ['a', 'b', 'c']Метод Сложность Подходит для Set O(n) Примитивы Цикл O(n²) Малые данные - Работает только с примитивными типами (числа, строки).
- Исключает NaN - Set считает все NaN разными.
- Идеален для 90% случаев.
Удаление дубликатов из массива объектов
Для объектов Set не сработает напрямую - сравнивает по ссылке. Нужно фильтровать по ключу, например id. Используем filter() с findIndex().
Возьмем [{id: 1}, {id: 2}, {id: 1}]. Фильтр оставляет первое вхождение каждого id. Логика: текущий индекс == индекс первого совпадения по id.
const items = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }, { id: 1, name: 'C' }]; const unique = items.filter((obj, idx, arr) => idx === arr.findIndex(t => t.id === obj.id) ); console.log(unique); // [{ id: 1, name: 'A' }, { id: 2, name: 'B' }]- findIndex() ищет первое совпадение.
- Сохраняет первый объект, удаляет последующие.
- Для нескольких ключей создайте функцию сравнения.
Методы filter и reduce для гибкости
Метод filter() с indexOf() проверяет первое вхождение элемента. Это альтернатива циклу, но тоже O(n²). Подходит, когда Set не годится.
Пример с reduce(): аккумулируем уникальные элементы, проверяя includes(). Более функциональный стиль, но медленнее Set.
Filter-реализация:
function removeDuplicates(arr) { return arr.filter((item, index) => arr.indexOf(item) === index); }Reduce-вариант:
const uniqueLetters = ['a','a','b','c'].reduce((result, letter) => result.includes(letter) ? result : [...result, letter], [] );Метод Сложность Когда использовать filter O(n²) Нет Set в окружении reduce O(n²) Функциональный стиль Set O(n) Стандартный случай - filter создает новый массив.
- reduce гибче для сложной логики.
- Избегайте на больших данных.
Продвинутые техники и оптимизации
Для массивов объектов по нескольким полям напишите isPropValuesEqual(). Сортировка + reduce ускоряет на повторяющихся id. Объект как хэш-таблица для примитивов.
Пример с объектами по двум ключам:
function isPropValuesEqual(obj1, obj2, props) { return props.every(prop => obj1[prop] === obj2[prop]); } const unique = items.filter((obj, idx, arr) => idx === arr.findIndex(t => isPropValuesEqual(t, obj, ['name', 'place'])) );- Сортировка: O(n log n) + reduce.
- Хэш-объект: obj[value] = true для уникальности.
- Тестируйте производительность на ваших данных.
Баланс скорости и читаемости кода
Set - лидер по скорости для простых случаев, но требует ES6. Для объектов комбинируйте filter с findIndex. Итеративные методы надежны в legacy-проектах.
Выбор зависит от данных: примитивы - Set, объекты - кастомный filter. На больших объемах измеряйте время. Экспериментируйте с reduce для цепочек операций.
© 2024 - 2026 ExLends, Inc. Все права защищены.