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; }, []); }