Как убрать дубли из массива
Вопрос
Как убрать дубликаты из массива чисел, а потом из массива объектов по полю id? Сравните варианты по сложности.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Примитивы: `[...new Set(arr)]`, O(n), порядок первых вхождений сохраняется
Вариант `filter` + `indexOf` работает, но O(n²)
Объекты по ключу: `Set` увиденных `id` и `filter`, оставляет первое вхождение
Через `new Map(arr.map(x => [x.id, x]))` остаётся последнее значение на позиции первого
Объекты без ключа сравниваются по ссылке, `Set` их не схлопнет
Крайние случаи: пустой массив, NaN, `id` разных типов (1 и '1')
Что могут спросить следом
- Как оставить последнее вхождение, а не первое?
- Как убрать дубли по нескольким полям сразу?
- Почему
new Set([{a:1}, {a:1}])даёт размер 2?
Разбор
Образцовый ответ: «Для чисел и строк самое простое: [...new Set(arr)]. Это O(n), порядок первых вхождений сохраняется, NaN тоже схлопывается, потому что Set сравнивает по SameValueZero. Классический вариант arr.filter((x, i) => arr.indexOf(x) === i) работает, но за O(n²) и не находит NaN. Для объектов Set не поможет: он сравнивает ссылки, и два одинаковых по содержимому объекта разные. Поэтому завожу Set увиденных id и фильтрую: если id уже был, пропускаю, иначе добавляю. Это O(n) и оставляет первое вхождение. Короткий вариант через Map с ключом id оставит последнее значение, но на позиции первого вхождения, это надо понимать. Для нескольких полей строю составной ключ, например ${a}|${b}. Ещё уточнил бы, могут ли id быть разного типа, 1 и '1' для Set разные значения».
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.