> Как реализовать рекурсивную чистую функцию для инверсии значений в объекте в JavaScript (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Домклик

Стек: JavaScript

> Пример ответа

Короткий ответ

Рекурсивная чистая функция для инверсии значений в объекте должна создавать новый объект, не мутируя исходный, и рекурсивно обрабатывать вложенные структуры. Инверсия подразумевает замену ключей на значения и наоборот, но при этом значения должны быть строками или числами, пригодными для использования в качестве ключей. Функция возвращает новый объект с инвертированными парами ключ-значение, рекурсивно обрабатывая вложенные объекты.

Подробное объяснение

Чистая функция - это функция, которая не имеет побочных эффектов и всегда возвращает одинаковый результат для одинаковых аргументов. Для инверсии значений в объекте это означает:

  • Создание нового объекта вместо изменения исходного
  • Отсутствие мутации входных данных
  • Предсказуемость результата

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

Ключевые моменты реализации:

  1. Проверка типа значения: если это не объект или null, возвращаем его как есть
  2. Для каждого ключа исходного объекта создаем новую пару: значение становится ключом, ключ - значением
  3. Если значение - объект, рекурсивно обрабатываем его
  4. Обработка коллизий: если несколько ключей имеют одинаковое значение, нужно решить, как объединять (например, в массив)

На практике

В реальных проектах такая функция полезна для трансформации данных, например, при работе с API, где нужно перестроить структуру ответа. Важно учитывать edge cases: массивы, null, функции, символы. Массивы обычно не инвертируются как объекты, их лучше обрабатывать отдельно или пропускать.

Функция должна быть иммутабельной - использовать spread оператор или Object.assign для создания новых объектов. Для глубокой рекурсии стоит учитывать возможное переполнение стека, но для типичных вложенностей это не проблема.

Пример кода

JAVASCRIPT
function invertObject(obj) {
// Проверка на null и не-объекты
if (obj === null || typeof obj !== 'object') {
return obj;
}
// Обработка массивов - возвращаем как есть или обрабатываем элементы
if (Array.isArray(obj)) {
return obj.map(invertObject);
}
const result = {};
for (const [key, value] of Object.entries(obj)) {
// Рекурсивно обрабатываем значение
const processedValue = invertObject(value);
// Значение должно быть строкой или числом для использования как ключ
const newKey = String(processedValue);
// Обработка коллизий: если ключ уже существует, объединяем в массив
if (result.hasOwnProperty(newKey)) {
const existing = result[newKey];
result[newKey] = Array.isArray(existing)
? [...existing, key]
: [existing, key];
} else {
result[newKey] = key;
}
}
return result;
}
// Пример использования
const input = {
name: 'John',
age: 30,
address: {
city: 'NY',
zip: '10001'
}
};
const inverted = invertObject(input);
// Результат:
// {
// "John": "name",
// "30": "age",
// "NY": "city",
// "10001": "zip"
// }

Как отвечать на собеседовании

Начни с определения чистой функции и рекурсии. Объясни, почему инверсия значений требует создания нового объекта. Покажи понимание edge cases: null, массивы, коллизии ключей. Упомяни, что значения должны быть приводимы к строке для использования в качестве ключей. Предложи варианты обработки коллизий (массив или перезапись). Продемонстрируй знание иммутабельности и отсутствия побочных эффектов.

Что проверяет интервьюер

  • Понимание концепции чистой функции и иммутабельности
  • Умение работать с рекурсией и базовыми случаями
  • Знание типов данных в JavaScript и их особенностей
  • Способность обрабатывать edge cases
  • Понимание работы с объектами и их перебором
  • Умение проектировать функции без побочных эффектов

Типичные ошибки

  • Мутация исходного объекта вместо создания нового
  • Игнорирование обработки null и массивов
  • Неучтенные коллизии ключей при инверсии
  • Использование for...in без hasOwnProperty
  • Отсутствие рекурсивной обработки вложенных объектов
  • Предположение, что все значения - строки
  • Забывание про цикличные ссылки (хотя для чистой функции это редкость)

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью