Рекурсивно перебирать вложенный объект, чтобы изменить значение ключа во всех случаях - PullRequest
0 голосов
/ 17 января 2019

Существует структура ввода с правилами, вложенными в другие правила. В массиве правил, где бы ни было свойство data, его значение должно быть изменено на «foo»

Примеры объектов ввода:

  1. {условие: 'и', правила: [{данные: '123'}]}

  2. {условие: 'или', правила: [{данные: '123'}, {условие: 'и', правила: [{данные: '123'}, {данные: '456'}] }]

Я рекурсивно вызываю функцию для итерации, и если у элемента есть свойство данных, меняем его значение

Моя функция:

function iterateRules(input) {
    input.rules.map(function(item) {
      if(_.has(item, "rules")){
        this.iterateRules(item); //bug-needs extra check like accepted answer 
      } else if(_.has(item, “data”)){
         return item.data = “foo”;
      }
    }, this);
   return input;
 }

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Существует рекурсивный подход для достижения этой цели:

const input = {condition: "and", rules: [ { data: "123"}, {condition: "and", rules: [{data:"456"}, {condition: "and", rules: [{value: "456"}]} ] } ]}

function test (obj) {
	if(!Object.keys(obj).includes('rules')) return;
	obj.rules.forEach(x => x.data ? x.data = 'foo' : x);
	return test(obj.rules.find(x => !Object.keys(x).includes('data')));
}

test(input)

console.log(input);

примечание: эта функция изменяет объект ввода.

0 голосов
/ 17 января 2019

В указанном вами коде есть потенциальная ошибка.

  1. В рекурсивном вызове iterateRules вы передаете input вместо item
  2. Вам также необходимо проверить, имеет ли input свойство rules

Попробуйте это -

function iterateRules(input) {
  if(_.has(input, "rules")) {
    input.rules.map(function(item) { 
      if(_.has(item, "rules")){
        this.iterateRules(item);
      } else if (_.has(item, "data")) {
          return item.data = "foo";
      }
    }, this);
    console.log(input);
  }
}
...