Извините, я не знаю, как правильно сформулировать этот вопрос, но в основном у меня есть этот вложенный объект nestedObj
. Я хочу динамически обрабатывать этот объект, но глубина объекта не фиксирована. Так, например:
nestedObj = {
"property1":{
"subProperty1": {
"data": "This is the data for property1 > subProperty1"
}
},
"property2":{
"subProperty1": {
"anotherSubProperty1": {
"data": "This is the data for property2 > subProperty1 > anotherSubProperty1"
}
},
"subProperty2": {
"anotherSubProperty1": {
"data": "This is the data for property2 > subProperty2 > anotherSubProperty1"
}
}
},
"property3":{
"subProperty1": {
"data": "This is the data for property3 > subProperty1"
}
}
}
Теперь я хочу обработать этот объект в цикле for of
, где моя конечная цель — получить значение data
определенных узлов. Теперь путь к значению каждого узла объекта определяется в другом объекте:
dataPath = {
"property1": "subProperty1.data",
"property2": "subProperty2.anotherSubProperty1.data",
"property3": "subProperty1.data",
}
А затем я использовал этот цикл for of
для их обработки:
properties = ["property1", "property2", "property3"];
for(var property of properties) {
path_to_data = dataPath[property].split(".");
data = nestedObj[path_to_data[0]][path_to_data[1]];
// Some other logic
}
Очевидно, это работает только для свойств «свойство1» и «свойство3». Я должен добавить специальную обработку для всех объектов, которые имеют более двух внутренних узлов. Для больших данных с разным числом глубины было бы не идеально вручную добавлять эти специальные обработчики. Итак, мой вопрос: в Javascript есть ли способ динамически обрабатывать вложенный объект, когда у меня есть «путь» к определенному узлу.
@MaheerAli Мне нужны только данные из указанных путей
@ akmalhakimi1991 Я обновил свой ответ. Надеюсь, я правильно понял, если нет, дайте мне знать, и я попробую еще раз.
Вы можете использовать reduce()
, чтобы получить значение от объекта с путем
const nestedObj = { "property1":{ "subProperty1": { "data": "This is the data for property1 > subProperty1" } }, "property2":{ "subProperty1": { "anotherSubProperty1": { "data": "This is the data for property2 > subProperty1 > anotherSubProperty1" } }, "subProperty2": { "anotherSubProperty1": { "data": "This is the data for property2 > subProperty2 > anotherSubProperty1" } } }, "property3":{ "subProperty1": { "data": "This is the data for property3 > subProperty1" } } }
const dataPath = { "property1": "subProperty1.data", "property2": "subProperty2.anotherSubProperty1.data", "property3": "subProperty1.data", }
let props = ["property1", "property2", "property3"];
const getValueFromObj = (obj,path) => path.split('.').reduce((ac,a) => (ac[a] || {}),obj);
let res = props.map(x => getValueFromObj(nestedObj,x+'.'+dataPath[x]))
console.info(res)
for..of
const nestedObj = { "property1":{ "subProperty1": { "data": "This is the data for property1 > subProperty1" } }, "property2":{ "subProperty1": { "anotherSubProperty1": { "data": "This is the data for property2 > subProperty1 > anotherSubProperty1" } }, "subProperty2": { "anotherSubProperty1": { "data": "This is the data for property2 > subProperty2 > anotherSubProperty1" } } }, "property3":{ "subProperty1": { "data": "This is the data for property3 > subProperty1" } } }
const dataPath = { "property1": "subProperty1.data", "property2": "subProperty2.anotherSubProperty1.data", "property3": "subProperty1.data", }
let props = ["property1", "property2", "property3"];
const getValueFromObj = (obj,path) => path.split('.').reduce((ac,a) => (ac[a] || {}),obj);
for(let prop of props){
let data = getValueFromObj(nestedObj,prop+'.'+dataPath[prop]);
console.info(data)
}
Спасибо. Это успешно дает значения на основе путей. Однако в моем исходном коде в цикле for of
гораздо больше логики (например, добавление значения в таблицу с помощью jQuery). Как мне сделать то же самое, если я использую ваше решение?
@ akmalhakimi1991 Посмотрите обновленный ответ и рассмотрите возможность принятия ответа, если он вас устраивает.
Спасибо. Именно то, что я ищу
_.get
lodash делает именно то, что вы хотите. Вы можете проверить исходный код, чтобы увидеть реализацию.
const nestedObj = { "property1":{ "subProperty1": { "data": "This is the data for property1 > subProperty1" } }, "property2":{ "subProperty1": { "anotherSubProperty1": { "data": "This is the data for property2 > subProperty1 > anotherSubProperty1" } }, "subProperty2": { "anotherSubProperty1": { "data": "This is the data for property2 > subProperty2 > anotherSubProperty1" } } }, "property3":{ "subProperty1": { "data": "This is the data for property3 > subProperty1" } } }
const dataPath = { "property1": "subProperty1.data", "property2": "subProperty2.anotherSubProperty1.data", "property3": "subProperty1.data", }
let props = ["property1", "property2", "property3"];
props.forEach(property => {
const nestedObjAtProperty = nestedObj[property]; // { "subProperty1": { "data": "This is the data for property1 > subProperty1" } }
const dataPathForProperty = dataPath[property]; // "subProperty1.data"
const data = _.get(nestedObjAtProperty, dataPathForProperty); // "This is the data for property1 > subProperty1"
console.info(data);
}
Вы можете использовать Object.keys
для перебора объекта dataPath
. Затем вы split
значение и используете его для цикла и отслеживаете data
.
let nestedObj = {
"property1": {
"subProperty1": {
"data": "This is the data for property1 > subProperty1"
}
},
"property2": {
"subProperty1": {
"anotherSubProperty1": {
"data": "This is the data for property2 > subProperty1 > anotherSubProperty1"
}
},
"subProperty2": {
"anotherSubProperty1": {
"data": "This is the data for property2 > subProperty2 > anotherSubProperty1"
}
}
},
"property3": {
"subProperty1": {
"data": "This is the data for property3 > subProperty1"
}
}
}
let dataPath = {
"property1": "subProperty1.data",
"property2": "subProperty2.anotherSubProperty1.data",
"property3": "subProperty1.data",
}
let properties = ["property1", "property2", "property3"]
for (let property of properties) {
let path = dataPath[property].split('.')
let data = nestedObj[property]
for (let i = 0; i < path.length; i++) {
data = data[path[i]]
if (i + 1 === path.length) {
console.info(data)
}
}
}
ОП сказал в комментарии «Мне нужны только данные из указанных путей»
@MaheerAli Я работаю над редактированием своего ответа, этот комментарий был сделан после моего ответа :)
Будут ли у вас пути для дополнительных данных или вы хотите получить все данные без указания путей