Как динамически обрабатывать вложенный объект в Javascript, если я не знаю, какова его глубина?

Извините, я не знаю, как правильно сформулировать этот вопрос, но в основном у меня есть этот вложенный объект 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 есть ли способ динамически обрабатывать вложенный объект, когда у меня есть «путь» к определенному узлу.

Будут ли у вас пути для дополнительных данных или вы хотите получить все данные без указания путей

Maheer Ali 27.05.2019 09:01

@MaheerAli Мне нужны только данные из указанных путей

akmalzamri 27.05.2019 09:08

@ akmalhakimi1991 Я обновил свой ответ. Надеюсь, я правильно понял, если нет, дайте мне знать, и я попробую еще раз.

Oliver Nybo 27.05.2019 09:46
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
76
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете использовать 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). Как мне сделать то же самое, если я использую ваше решение?

akmalzamri 27.05.2019 09:25

@ akmalhakimi1991 Посмотрите обновленный ответ и рассмотрите возможность принятия ответа, если он вас устраивает.

Maheer Ali 27.05.2019 09:34

Спасибо. Именно то, что я ищу

akmalzamri 27.05.2019 10:24

_.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)
        }
    }
}

ОП сказал в комментарии «Мне нужны только данные из указанных путей»

Maheer Ali 27.05.2019 09:12

@MaheerAli Я работаю над редактированием своего ответа, этот комментарий был сделан после моего ответа :)

Oliver Nybo 27.05.2019 09:21

Другие вопросы по теме