Я не думаю, что это плохо, что это реализовано рекурсивным способом.Это лучший способ справиться с рекурсивными структурами данных, такими как объекты JS.
Но вы всегда можете преобразовать рекурсивные решения в итеративные, если вы хотите управлять своим собственным стеком.Вот довольно уродливый подход, но, похоже, он подходит для этого простого теста:
const flattenObj = (obj) => {
const results = [];
const steps = Object.entries(obj)
while (steps.length) {
const [key, val] = steps.splice(0, 1)[0]
if (typeof val == 'object') {
Array.prototype.push.apply(steps, Object.entries(val).map(
([k, v]) => [key + '.' + k, v]
))
} else {
results.push([key, val])
}
}
return results.reduce((a, [k, v]) => ({...a, [k]: v}), {})
}
const foo = {a:1, b:{c:3}, d:{e:{f:6}, g:[{h:8, i:9}, 0]}}
console.log(flattenObj(foo))
Это не будет работать с циклическими структурами, но версия кулинарной книги тоже не будет, предположительно.
Я написал это изначально, используя некоторые функции Ramda (toPairs
вместо Object.entries
, is(Object, val)
вместо typeof val == 'object'
и return fromPairs(results)
вместо return results.reduce(...)
.) Но при всей происходящей мутации (splice
и push
) он чувствуеточень unRamda-иш решение, и я удалил их.(Вы понимаете, что функции Рамды не хотят ассоциироваться с изменчивостью!)
Я не знаю, решит ли это вашу проблему.Я использовал flattenObj
только несколько раз, хотя я вижу утилиту в тестах.Но мне кажется, что если это вызывает проблемы рекурсии, циклические структуры данных являются более вероятной проблемой, чем фактическая глубина.Но, конечно, я не знаю ваших данных, так кто знает?