Интервью-вопрос
Как проверить, является ли массив уникальным
Для примитивов обычно достаточно сравнить размер Set с длиной массива. Главное на интервью: назвать это решение и не забыть ограничения для объектов, NaN и ручных проверок.
- Добавлен
- Редакция
Подготовьте короткий ответ и пару деталей на случай уточняющих вопросов.
Мини-квиз
Проверка перед разбором
Несколько быстрых вопросов перед разбором. Так проще поймать места, которые только кажутся понятными.
Вопрос 1 из 50 правильно
Разбор
Разобраться, а не зазубрить
Дальше разбираем суть, типичные уточнения и места, где легко сказать лишнее или перепутать термины.
Базовая идея
Самый короткий ответ для интервью выглядит так:
const isUnique = (arr) => new Set(arr).size === arr.length;Если в массиве был повтор, размер Set станет меньше длины массива. Если размеры равны, каждый элемент встретился один раз.
Такой ответ хорошо работает для примитивов: строк, чисел, boolean, null, undefined, symbol и bigint. Практический риск начинается там, где вы не уточнили тип элементов и критерий уникальности.
Что важно уточнить в ответе
Уникальность почти всегда зависит от смысла данных. Массив чисел уникален, если нет одинаковых чисел. Массив пользователей может быть уникален по id, по email или по паре полей. Это разные проверки.
Сильная формулировка:
Если это массив примитивов, я сравню размер Set с длиной массива. Если это массив объектов, сначала уточню критерий уникальности, например id, и буду проверять этот ключ.
Как выбрать подход
Используйте `new Set(arr).size === arr.length` или цикл с Set для раннего выхода.Сравнивайте выбранный ключ, например `user.id`, а не весь объект.Соберите стабильный ключ из нормализованных частей, например `country + ':' + phone`.Считайте результат при изменении данных или мемоизируйте его. Не запускайте проверку без причины на каждом рендере.Пример для объектов
Плохой вариант, если вам нужна уникальность пользователей по id:
const users = [{ id: 1 }, { id: 1 }];
const unique = new Set(users).size === users.length; // trueЭтот код говорит, что массив уникален, потому что в нем две разные ссылки на объекты. Для UI это может привести к дублирующимся строкам в таблице, повторным опциям в селекте или неверной валидации формы.
Безопаснее проверять выбранный ключ:
const isUniqueBy = (items, getKey) => {
const seen = new Set();
for (const item of items) {
const key = getKey(item);
if (seen.has(key)) {
return false;
}
seen.add(key);
}
return true;
};
const usersAreUnique = isUniqueBy(users, (user) => user.id);Здесь есть ранний выход. Как только найден дубликат, функция сразу возвращает false. Это полезно для больших списков и валидации, которая запускается часто.
Ловушки сравнения
Set использует алгоритм SameValueZero. Для собеседования достаточно помнить два практических следствия: NaN считается равным NaN, а +0 и -0 считаются одним значением.
new Set([NaN, NaN]).size; // 1
new Set([+0, -0]).size; // 1Если вы пишете ручную проверку через ===, поведение с NaN может отличаться. Это важно для данных из формы, парсинга чисел или API.
- 1Назвать короткое решение через Set
- 2Уточнить, что это про примитивы
- 3Сказать про объекты по ссылке
- 4Предложить ключ или функцию сравнения
- 1Сказать, что Set решает все случаи
- 2Не упомянуть NaN и ссылки
- 3Использовать объект как словарь без оговорок
- 4Предложить JSON.stringify как универсальный способ
Практический вывод
На интервью не стоит останавливаться только на одной строке кода. Лучше дать короткое решение, затем сразу показать границы применимости.
Хороший ответ:
Для примитивов я проверю new Set(arr).size === arr.length. Это линейная проверка по времени и памяти. Если элементы являются объектами, Set сравнит ссылки, поэтому я выберу ключ уникальности, например id, и буду хранить в Set уже эти ключи.
Если проверка запускается во frontend на каждом вводе пользователя, подумайте о стоимости. Для маленьких массивов простая читаемая проверка нормальна. Для больших списков лучше остановка при первом дубликате, а в React не стоит пересчитывать тяжелую проверку на каждом рендере без изменения данных.
Не используйте проверку уникальности как способ молча "починить" данные от API. Если сервер вернул дубли, UI должен либо показать понятную ошибку, либо явно удалить повторы по согласованному ключу. Иначе пользователь может выбрать не тот элемент, увидеть неверное состояние или отправить лишний запрос.
Частые ошибки
Где обычно ошибаются
Проверьте формулировки, которые звучат уверенно, но на интервью быстро выдают пробелы.
- 1
Проверять объекты через Set как примитивы
new Set(users).sizeсравнит ссылки на объекты, а не их поля. Два объекта с одинаковымidостанутся разными значениями. Если бизнес-смысл вid, проверяйте именноid. Иначе в UI могут появиться дубли строк, опций или выбранных элементов. - 2
Использовать обычный объект как универсальный словарь
Ключи обычного объекта приводятся к строкам, поэтому разные значения могут слиться в один ключ. Например, разные объекты превращаются в похожий строковый ключ. Для произвольных значений лучше использоватьMapилиSet, а для объектов заранее выбирать стабильный ключ. - 3
Забывать про NaN в ручной проверке
Проверка через===не считаетNaNравным самому себе. Если вы пишете вложенные циклы, дваNaNмогут ошибочно пройти как уникальные.Setэтот случай обрабатывает безопаснее. - 4
Считать JSON.stringify глубоким сравнением
JSON.stringifyзависит от формы данных и не сохраняет часть значений, напримерundefinedв объектах. Это может дать ложную уникальность или ложные дубликаты. Если нужна глубокая уникальность, лучше явно нормализовать данные или выбрать проверенную функцию сравнения. - 5
Лечить дубли в React индексом массива
Если данные не уникальны,key={index}только маскирует проблему. При сортировке, фильтрации или удалении React может переиспользовать не тот DOM-узел. Пользователь увидит неверное состояние строки или инпута. Безопаснее убрать дубли на уровне данных и использовать стабильный ключ.
Follow-up
Что могут спросить дальше
Короткие ответы на вопросы, которыми проверяют понимание Set, сравнения значений и практических ограничений.
Живые ответы
Видео с похожим вопросом
Если найдем публичные интервью с таким вопросом, добавим их сюда. Их удобно смотреть после теории, чтобы свериться с живыми ответами.
Пока видео нет. Когда появятся подходящие публичные интервью, добавим их в этот блок, чтобы можно было сравнить разбор с тем, как отвечают реальные кандидаты.
Из-за чего ломается рекурсия при работе с большими числами 😎
Рекурсия в JavaScript чаще всего ломается из-за переполнения стека вызовов, а не из-за самого числа. Разбираем, как объяснить это на интервью и чем заменить глубокую рекурсию во frontend-коде.
Какая алгоритмическая сложность при сортировке массива в JavaScript 😎
У Array.prototype.sort нет гарантированной стандартом сложности, но в современных движках обычно ожидают O(n log n). Разберем, как ответить про sort, comparator, мутацию массива и риски для frontend-кода.