【问题标题】:Recursively iterate over a nested object to change a key value on all occurrences递归迭代嵌套对象以更改所有出现的键值
【发布时间】:2019-06-11 05:35:59
【问题描述】:

有一个规则嵌套在其他规则中的输入结构。在规则数组中,只要有 'data' 属性,其值必须更改为“foo”

示例输入对象:

  1. {条件:'and',规则:[{data:'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;
 }

【问题讨论】:

  • 如果您的示例使用常规的直引号并且没有像 [value: ‘456”] 这样的语法错误,将会很有帮助
  • 另外,您需要原地更换商品还是退回新商品?
  • @MarkMeyer 我想返回整个更改的对象。我在代码中的错误是,我没有返回,并且额外检查它是否有递归调用的规则帮助(如在批准的答案中)

标签: javascript angular recursion lodash iterated-function


【解决方案1】:

您提到的代码中存在潜在错误。

  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);
  }
}

【讨论】:

  • 在这里传递输入而不是项目是一个错字。但额外的条件有所帮助。并且之前没有将输入返回给该函数的调用者。
【解决方案2】:

有一种递归方法可以实现这一点:

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);

注意:这个函数改变输入对象。

【讨论】:

    猜你喜欢
    • 2020-12-01
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    • 2020-11-19
    • 2018-06-21
    相关资源
    最近更新 更多