I’m writing a recursive function on a JSON tree {name, type, [children]}
to remove nodes of a certain type. However, the children of the removed node should get re-attached to the parent, if they are not of the type to be removed.
I’m experiencing the following difficulty: Let’s say I want to remove type b on the following tree:
const sampleData = [{
name: "parent",
type: "a",
children: [{
name: "childA",
type: "a",
children: null
},{
name: "childB",
type: "b",
children: [{
name: "grandChildA",
type: "a",
children: null
},{
name: "grandChildB",
type: "a",
children: null
}]
},{
name: "childC",
type: "a",
children: null
}]
}]
The original children for parent is [childA, childB, childC]
.
After the removal, the parent should have children [childA, grandChildA, grandChildB, childC]
.
However, the result I’m getting is [childA, [grandChildA, grandChildB], childC]
.
I know I need to spread it out, but I’m not sure where to do it in the recusion.
Here’s the function that I have right now (I know I’m using the spread syntax in the wrong place):
const removeType = (node, type) => {
//if the node should not be removed
if (node.type !== type){
//if the node has children, recursively call to prune children
if (node.children && node.children.length > 0){
node.children = [node.children.map(child => removeType(child, type))
.filter(child => child !== null)]
return node
}
//if the node has no children, return the node
else return node
}
//if the node should be removed
else if (node.type === type){
//if the node has children, recursively call, then reattach the children
if (node.children && node.children.length > 0){
node.children = [node.children.map(child => removeType(child, type))
.filter(child => child !== null)]
return node.children
}
//
else return null
}
}
Advertisement
Answer
Updated
I think you can use reduce for that, I’m not having my computer right now to test it, but it’ll be something like this
const removeType = (node, type) => {
if (node === null) {
return null;
} else {
return node.reduce((acc, child) => {
if(child["type"] === type) {
const removedChild = removeType(child["children"], type);
acc = [acc, removedChild];
} else {
child.children = removeType(child["children"], type);
acc.push(child);
}
return acc;
}, []);
}
}
2nd Update
Code reduced:
const removeType = (node, type) => {
if (!node) return;
return node.reduce((acc, child) => {
if(child["type"] === type) {
const removedChild = removeType(child["children"], type);
acc = [acc, removedChild];
} else {
child.children = removeType(child["children"], type);
acc.push(child);
}
return acc;
}, []);
}