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