0

I have a nested object and I want to find the splice every 0th index key "logic" & value in it. Let's say object looks like this:

Original input:

[
  {
    "conditions": [
      {
        "logic": "AND",
        "parameter": "Risk Engine Score",
        "condition": "Equals",
        "value": "122",
        "level": "first",
        "type": "condition"
      },
      {
        "level": "second",
        "type": "group",
        "nextChildLogic": "AND",
        "conditions": [
          {
            "logic": "AND",
            "parameter": "Risk Engine Score",
            "condition": "Equals",
            "value": "123",
            "level": "second",
            "type": "condition"
          }
        ],
        "groupLogic": "AND"
      }
    ],
    "modeOfAuth": "otp"
  },
  {
    "conditions": [
      {
        "logic": "AND",
        "parameter": "Risk Engine Score",
        "condition": "< Less than",
        "value": "12",
        "level": "first",
        "type": "condition"
      }
    ],
    "modeOfAuth": "frictionless"
  },
  {
    "conditions": [
      {
        "logic": "AND",
        "parameter": "Risk Engine Score",
        "condition": "Equals",
        "value": "12",
        "level": "first",
        "type": "condition"
      },
      {
        "level": "second",
        "type": "group",
        "nextChildLogic": "AND",
        "conditions": [
          {
            "logic": "AND",
            "parameter": "Amount",
            "condition": "< Less than",
            "value": "12",
            "level": "second",
            "type": "condition"
          }
        ],
        "groupLogic": "AND"
      }
    ],
    "modeOfAuth": "frictionless"
  }
]

Code:

for(var i=0;i〈conditionItem.length;i++)
    {
      // conditionItem[0].splice(conditionItem.indexOf(logic), 1);


      // console.log("ccc=",conditionItem)
      if(Array.isArray(conditionItem[i].condition))
      {
        var conditionItem1=[];
        for(var j=0;j〈conditionItem.length;j++)
        {
          if(j==0)
          {
            conditionItem1.push({"condition":conditionItem[j].condition,"level":conditionItem[j].level,"parameter":conditionItem[j].parameter,"type":conditionItem[j].type,"value":conditionItem[j].value})
          }else{
            conditionItem1.push(conditionItem[j])
          }

        }
        conditionItem[i].condition = conditionItem1;        
      }

    }
    console.log("conditionItem::=",conditionItem);

for(var i=0;i〈conditionItem.length;i++)
    {
      // conditionItem[0].splice(conditionItem.indexOf(logic), 1);


      // console.log("ccc=",conditionItem)
      if(Array.isArray(conditionItem[i].condition))
      {
        var conditionItem1=[];
        for(var j=0;j〈conditionItem.length;j++)
        {
          if(j==0)
          {
            conditionItem1.push({"condition":conditionItem[j].condition,"level":conditionItem[j].level,"parameter":conditionItem[j].parameter,"type":conditionItem[j].type,"value":conditionItem[j].value})
          }else{
            conditionItem1.push(conditionItem[j])
          }

        }
        conditionItem[i].condition = conditionItem1;        
      }

    }
    console.log("conditionItem::=",conditionItem);

expected output:

[
  {
    "conditions": [
      {

        "parameter": "Risk Engine Score",
        "condition": "Equals",
        "value": "122",
        "level": "first",
        "type": "condition"
      },
      {
        "level": "second",
        "type": "group",
        "nextChildLogic": "AND",
        "conditions": [
          {

            "parameter": "Risk Engine Score",
            "condition": "Equals",
            "value": "123",
            "level": "second",
            "type": "condition"
          }
        ],
        "groupLogic": "AND"
      }
    ],
    "modeOfAuth": "otp"
  },
  {
    "conditions": [
      {
        "parameter": "Risk Engine Score",
        "condition": "< Less than",
        "value": "12",
        "level": "first",
        "type": "condition"
      }
    ],
    "modeOfAuth": "frictionless"
  },
  {
    "conditions": [
      {

        "parameter": "Risk Engine Score",
        "condition": "Equals",
        "value": "12",
        "level": "first",
        "type": "condition"
      },
      {
        "level": "second",
        "type": "group",
        "nextChildLogic": "AND",
        "conditions": [
          {

            "parameter": "Amount",
            "condition": "< Less than",
            "value": "12",
            "level": "second",
            "type": "condition"
          }
        ],
        "groupLogic": "AND"
      }
    ],
    "modeOfAuth": "frictionless"
  }
]
Kévin Bibollet
  • 3,573
  • 1
  • 15
  • 33
Puneeth Kumar
  • 182
  • 2
  • 14
  • 1
    Please post a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) of your attempt note exactly where you're stuck. – Scott Sauyet May 14 '19 at 12:45
  • Every condition is an object, not an array. You can simply [remove the `logic` property](https://stackoverflow.com/questions/208105/how-do-i-remove-a-property-from-a-javascript-object). – 3limin4t0r May 14 '19 at 14:45

2 Answers2

1

The most elegant and short way I could think of is using map and some recursion:

// setting a default empty array in case the *initial* object has no condition key
const parseData = ({ conditions = [], ...rest }) => {
  const cond = conditions.map(({ logic, ...condition }) => {
    if (condition.conditions) {
      return parseData(condition);
    }
    return condition;
  });

  return {
    conditions: cond,
    ...rest
  };
};

Breakdown:

  1. iterating over each element
  2. destructuring (extracting) conditions while keeping the rest under rest
  3. iterating over the extracted conditions
  4. extracting logic the same way we did in #2
  5. if our condition has its own conditions - we'll call parseData again, otherwise - returning a new object using spread syntax combined with conditions minus the extracted logic along with everything not conditions which we previously extracted into rest

An important note pointed out by @3limin4t0r: the object rest destruction assignment is currently still a stage 3 proposal. It's already has support from the major browsers, however the spec might change. Here are some thoughts on the matter: https://stackoverflow.com/a/48150001/1194694

A working example:

const data = [ { "conditions": [ { "logic": "AND", "parameter": "Risk Engine Score", "condition": "Equals", "value": "122", "level": "first", "type": "condition" }, { "level": "second", "type": "group", "nextChildLogic": "AND", "conditions": [ { "logic": "AND", "parameter": "Risk Engine Score", "condition": "Equals", "value": "123", "level": "second", "type": "condition" } ], "groupLogic": "AND" } ], "modeOfAuth": "otp" }, { "conditions": [ { "logic": "AND", "parameter": "Risk Engine Score", "condition": "< Less than", "value": "12", "level": "first", "type": "condition" } ], "modeOfAuth": "frictionless" }, { "conditions": [ { "logic": "AND", "parameter": "Risk Engine Score", "condition": "Equals", "value": "12", "level": "first", "type": "condition" }, { "level": "second", "type": "group", "nextChildLogic": "AND", "conditions": [ { "logic": "AND", "parameter": "Amount", "condition": "< Less than", "value": "12", "level": "second", "type": "condition" } ], "groupLogic": "AND" } ], "modeOfAuth": "frictionless" } ]

const parseData = ({ conditions = [], ...rest }) => {
  const cond = conditions.map(({ logic, ...condition }) => {
    if (condition.conditions) {
      return parseData(condition);
    }
    return condition;
  });

  return {
    conditions: cond,
    ...rest
  };
};

console.log(data.map(parseData));
silicakes
  • 6,364
  • 3
  • 28
  • 39
  • It might be worth noting that the object rest destruction assignment is currently still a stage 3 proposal. [As mentioned in the documentation you linked](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Rest_in_Object_Destructuring). Furthermore your current solution doesn't match the expected output. It doesn't remove nested `"logic"` properties. Eg. `root[0].conditions[1].conditions[0].logic` (from the input) is still present in the output. – 3limin4t0r May 14 '19 at 15:09
  • You're absolutely right! missed out no that, sorry. Will edit my answer – silicakes May 14 '19 at 16:07
0

The thing that comes to mind is to build a recursive function that handles this. You can remove/delete properties using the delete keyword. Keep in mind that this solution mutates the contents of the data variable.

This solution assumes that if further conditions are added, they are in the same format as the second condition.

var data = [{"conditions": [{"logic": "AND", "parameter": "Risk Engine Score", "condition": "Equals", "value": "122", "level": "first", "type": "condition"}, {"level": "second", "type": "group", "nextChildLogic": "AND", "conditions": [{"logic": "AND", "parameter": "Risk Engine Score", "condition": "Equals", "value": "123", "level": "second", "type": "condition"}], "groupLogic": "AND"}], "modeOfAuth": "otp"}, {"conditions": [{"logic": "AND", "parameter": "Risk Engine Score", "condition": "< Less than", "value": "12", "level": "first", "type": "condition"}], "modeOfAuth": "frictionless"}, {"conditions": [{"logic": "AND", "parameter": "Risk Engine Score", "condition": "Equals", "value": "12", "level": "first", "type": "condition"}, {"level": "second", "type": "group", "nextChildLogic": "AND", "conditions": [{"logic": "AND", "parameter": "Amount", "condition": "< Less than", "value": "12", "level": "second", "type": "condition"}], "groupLogic": "AND"}], "modeOfAuth": "frictionless"}];

function updateConditions(conditions) {
  // guard against empty arrays
  if (!conditions.length) return;

  // split the conditions into head and tail
  var [head, ...tail] = conditions;

  // remove the logic property
  delete head.logic;

  // update tail conditions
  tail.forEach(condition => updateConditions(condition.conditions));
}

data.forEach(obj => updateConditions(obj.conditions));
console.log(data);
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
  • If the logic for a property gets more complicated, consider moving the logic to a separate function `function updateCondition(condition) { /* ... */ }` then replace `delete head.logic;` with `updateCondition(head);`. – 3limin4t0r May 14 '19 at 15:51
  • You might like to add that this will cause the original object to mutate, in which case it might change for all elements that hold a reference to it. – silicakes May 15 '19 at 11:51