#javascript #node.js #object
Вопрос:
Как можно выполнить итерацию через глубоко вложенный объект, извлекая путь к каждому ключу, содержащему значение.
Демонстрационный объект ввода
{
nested: {
nested2: {
nested3: '123'
},
nested4: '456'
}
}
желаемый результат
nested.nested2.nested3
nested.nested4
Ответ №1:
Вы можете рекурсивно посещать узлы, сохраняя ссылку на стек. Я изменил объект, добавив пример массива.
Я просто соединяю путь разделителями точек, а затем преобразую цифровые клавиши в обозначения в скобках, используя следующее регулярное выражение.
/(?:.)(d )(?![a-z_])/ig
Я объединил несоответствующую группу (начинается с точки) и с отрицательным заголовком (не предшествует букве).
В качестве альтернативы можно использовать следующее выражение:
/(?:.)(d )(?=.)/g
Я заменил отрицательный внешний вид на положительный. Я, по сути, перевернул выражение, что может быть лучше для данной ситуации.
const obj = {
nested: {
nested2: [
{ nested3: '123' },
{ nested4: '456' }
],
nested5: '789'
}
};
const visitNodes = (obj, visitor, stack = []) => {
if (typeof obj === 'object') {
for (let key in obj) {
visitNodes(obj[key], visitor, [...stack, key]);
}
} else {
visitor(stack.join('.').replace(/(?:.)(d )(?![a-z_])/ig, '[$1]'), obj);
}
}
visitNodes(obj, (path, value) => console.log(`${path} = ${value}`));
Комментарии:
1. Большое вам спасибо, я не мог уследить за стеком в том, что написал.
2. @GregManiak Я исправил флаги регулярных выражений и обновил/исправил некоторые формулировки.
Ответ №2:
Вот краткое решение с использованием Array.reduce
:
const obj = {
nested: {
nested2: {
nested3: '123'
},
nested4: '456'
}
};
const r = (e, c = "") => Object.keys(e).reduce((t, y) => Array.isArray(e[y]) ? t : "object" == typeof e[y] ? [...t, ...r(e[y], c y ".")] : [...t, c y], []);
var s = r(obj)
console.log(s);
Комментарии:
1. Прекрасный синтаксис — и такой интуитивно понятный 😉
2. Я бы тоже подошел к этому таким образом, но для некоторых переменных и некоторых разрывов строк можно было бы использовать более длинные имена.
Ответ №3:
Вам придется выполнять рекурсию по путям объекта, пока он не достигнет чего-то, что не является объектом, и в этот момент он должен зарегистрировать путь до этой точки.
var x = {
nested: {
nested2: {
nested3: '123'
},
nested4: '456'
}
};
const printPaths = (obj, parentPath) => {
if (typeof obj === "object" amp;amp; !Array.isArray(obj)) {
const layerKeys = Object.keys(obj);
for (const ky of layerKeys) {
const newKey = parentPath ? `${parentPath}.${ky}` : ky;
printPaths(obj[ky], newKey);
}
} else if (parentPath) {
console.log(parentPath);
}
};
printPaths(x);