Home > database >  Update an deeply nested array of objects based on an object : Javascript
Update an deeply nested array of objects based on an object : Javascript

Time:10-07

I am having an deeply nested array of objects with certain properties, and given an object as input, it should update that object along with its children recursively. The format it has is as follows,

const arr = [
  {
    name: "parent",
    children: [
      {
        name: "child1",
        children: [
          {
            name: "granchild1",
            children: [],
            class: "level-2 leaf",
            config: {
              name: "granchild1",
              value1: false,
              value2: false
            }
          }
        ],
        class: "level-1 leaf",
        config: {
          name: "child1",
          value1: false,
          value2: false
        }
      },
      {
        name: "child2",
        children: [],
        class: "level-1 leaf",
        config: {
          name: "child2",
          value1: false,
          value2: false
        }
      }
    ],
    class: "level-0 group",
    config: {
      name: "parent",
      value1: false,
      value2: false
    }
  }
];

The given input object will look like

const obj = {
  name: "parent",
  value1: true,
  value2: true
};

Given this input, the object with matching name should update it's and children's value1 and value2 with the obj's values

Output should look like

const result = [
  {
    name: "parent",
    children: [
      {
        name: "child1",
        children: [
          {
            name: "granchild1",
            children: [],
            class: "level-2 leaf",
            config: {
              name: "granchild1",
              value1: true,
              value2: true
            }
          }
        ],
        class: "level-1 leaf",
        config: {
          name: "child1",
          value1: true,
          value2: true
        }
      },
      {
        name: "child2",
        children: [],
        class: "level-1 leaf",
        config: {
          name: "child2",
          value1: true,
          value2: true
        }
      }
    ],
    class: "level-0 group",
    config: {
      name: "parent",
      value1: true,
      value2: true
    }
  }
];

Code that I tried. How do I achieve the same output

const res = arr.map((item) => {
  let foundItem = arr.find((item) => item.name === obj.name);
  return {
    ...foundItem,
    children: {
      value1: obj.value1,
      value2: obj.value2
    }
  };
});

CodePudding user response:

You need a recursive function that passes along whether the desired parent was found in one of its ancestors.

const arr=[{name:"parent",children:[{name:"child1",children:[{name:"granchild1",children:[],class:"level-2 leaf",config:{name:"granchild1",value1:!1,value2:!1}}],class:"level-1 leaf",config:{name:"child1",value1:!1,value2:!1}},{name:"child2",children:[],class:"level-1 leaf",config:{name:"child2",value1:!1,value2:!1}}],class:"level-0 group",config:{name:"parent",value1:!1,value2:!1}}];

const recurse = (arr, nameToFind, objToMerge, inAncestor = false) => {
  return arr.map(obj => {
    const mergeThis = inAncestor || obj.name === nameToFind;
    const merged = !mergeThis ? obj : { ...obj, config: { ...obj.config, ...objToMerge } };
    if (merged.children) {
      merged.children = recurse(merged.children, nameToFind, objToMerge, mergeThis);
    }
    return merged;
  });
};
const obj = {
  name: "parent",
  value1: true,
  value2: true
};
const { name, ...objToMerge } = obj;
const result = recurse(arr, name, objToMerge);
console.log(result);

  • Related