← Назад к вопросам
Преобразование строки в nested объект
2.0 Middle🔥 101 комментариев
#Алгоритмы и структуры данных
Условие
Напишите функцию, которая преобразует строку с точками в nested объект:
function stringToNestedObject(str, value) {
// Ваш код
}
console.log(stringToNestedObject("a.b.c", 42));
// { a: { b: { c: 42 } } }
console.log(stringToNestedObject("user.name.first", "John"));
// { user: { name: { first: "John" } } }
Что проверяется
- Работа со строками (split)
- Динамическое создание объектов
- Рекурсия или reduce
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Эта задача требует создания вложенной структуры объектов, где каждая точка в строке представляет уровень вложенности. Разберу несколько подходов.
Подход 1: С использованием reduce (элегантный)
function stringToNestedObject(str: string, value: any): Record<string, any> {
// Разбиваем строку по точкам
const keys = str.split(".");
// Идём с конца и создаём объекты
return keys.reduceRight((acc, key) => {
return { [key]: acc };
}, value);
}
// Примеры:
console.log(stringToNestedObject("a.b.c", 42));
// { a: { b: { c: 42 } } }
console.log(stringToNestedObject("user.name.first", "John"));
// { user: { name: { first: "John" } } }
Как работает:
- Разбиваем строку "a.b.c" на массив ["a", "b", "c"]
reduceRightидёт справа налево (от конца)- Стартуем с
value(42) - На каждом шаге оборачиваем текущий аккумулятор в новый объект с ключом
- Итераций: { c: 42 } → { b: { c: 42 } } → { a: { b: { c: 42 } } }
Временная сложность: O(n) где n = количество точек Пространственная сложность: O(n) для создания новых объектов
Подход 2: С использованием простого цикла (читаемо)
function stringToNestedObject(str: string, value: any): Record<string, any> {
const keys = str.split(".");
let result = value;
// Идём с конца к началу
for (let i = keys.length - 1; i >= 0; i--) {
const key = keys[i];
result = { [key]: result };
}
return result;
}
Преимущества:
- Явная логика цикла легче понять
- Легче отлаживать
- Не требует понимания reduceRight
Подход 3: С использованием рекурсии
function stringToNestedObject(str: string, value: any): Record<string, any> {
const keys = str.split(".");
function buildNested(index: number): Record<string, any> {
// Базовый случай: если дошли до конца
if (index === keys.length) {
return value;
}
// Рекурсивный случай
const key = keys[index];
return {
[key]: buildNested(index + 1)
};
}
return buildNested(0);
}
Особенности:
- Классическая рекурсия
- Прямой проход (слева направо), но через замыкание создаём объекты справа
- Может привести к stackoverflow на очень глубоких путях
Подход 4: Прямой reduceRight с более понятным синтаксисом
function stringToNestedObject(str: string, value: any): Record<string, any> {
const keys = str.split(".");
return keys.reduceRight((acc, key) => {
const result: Record<string, any> = {};
result[key] = acc;
return result;
}, value);
}
Легче читать, чем { [key]: acc } синтаксис
Подход 5: Для глубокого доступа (бонус)
Если нужна функция для установки значения по пути (обратная операция для get):
function setNestedValue(obj: any, path: string, value: any): void {
const keys = path.split(".");
let current = obj;
// Идём до предпоследнего ключа
for (let i = 0; i < keys.length - 1; i++) {
const key = keys[i];
if (!(key in current) || typeof current[key] !== "object") {
current[key] = {};
}
current = current[key];
}
// Устанавливаем значение на последний ключ
current[keys[keys.length - 1]] = value;
}
// Использование
const obj = {};
setNestedValue(obj, "user.profile.name", "Alice");
console.log(obj); // { user: { profile: { name: "Alice" } } }
Тестирование
// Базовые тесты
const test1 = stringToNestedObject("a.b.c", 42);
console.log(test1.a.b.c === 42); // true
const test2 = stringToNestedObject("user.name.first", "John");
console.log(test2.user.name.first === "John"); // true
// Граничные случаи
console.log(stringToNestedObject("single", 99));
// { single: 99 }
console.log(stringToNestedObject("a.b", null));
// { a: { b: null } }
console.log(stringToNestedObject("x.y.z", { nested: true }));
// { x: { y: { z: { nested: true } } } }
// Глубокий объект
const deep = stringToNestedObject("a.b.c.d.e.f", "deep");
console.log(deep.a.b.c.d.e.f === "deep"); // true
Сравнение подходов
| Подход | Время | Читаемость | Рекомендуется |
|---|---|---|---|
| reduceRight | O(n) | Средняя | Production, FP-стиль |
| Простой цикл | O(n) | Отличная | Интервью, новички |
| Рекурсия | O(n) | Средняя | Примеры, алгоритмы |
| Улучшенный reduce | O(n) | Хорошая | Когда reduce обязателен |
Рекомендация для интервью
Начните с простого цикла справа налево — это наиболее понятно и показывает понимание алгоритма. Если интервьюер попросит функциональный подход, покажите reduceRight.
Ключевые моменты:
- Разбиваем строку по точкам
- Идём справа налево (от конца массива)
- Оборачиваем значение в объекты уровень за уровнем
- Временная сложность O(n) — один проход по массиву ключей
- На каждом шаге создаём новый объект