Search code examples
javascriptangularrecursionlodashiterated-function

Recursively iterate over a nested object to change a key value on all occurrences


There is an input structure with rules nested inside other rules. In the rules array, wherever there is a 'data' property, its value has to be changed to "foo"

Sample input objects:

  1. {condition: 'and', rules: [{data: '123'}]}

  2. {condition: 'or', rules: [ { data: '123'}, {condition: 'and', rules: [{data:'123'},{ data:'456'}] }]

Am recursively calling a function to iterate over and if the item has data property, changing its value

My function:

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

Solution

  • There is a potential bug in the code you mentioned.

    1. In the recursive call to iterateRules you are passing input instead of item
    2. You also need to check if the input has rules property

    Try this -

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