so I have the following tree structure:
const tree = {
id: "1",
tag: "pending",
subtasks: [
{ id: "2", tag: "pending", subtasks: [] },
{
id: "3",
tag: "in progress",
subtasks: [
{
id: "4",
tag: "pending",
subtasks: [
{
id: "6",
tag: "in progress",
subtasks: [
{
id: "10",
tag: "pending",
subtasks: [{ id: "11", tag: "complete", subtasks: [] }]
}
]
},
{ id: "7", tag: "complete", subtasks: [] }
]
},
{ id: "5", tag: "pending", subtasks: [] }
]
},
{ id: "4", tag: "complete", subtasks: [] }
]
};
and I want to remove any node that has the "in progress" tag
. But, I also want to keep the children of the removed node if their tag
s are not "in progress" out. They will be kept by moving them to the same depth and index levels of their parent.
so, the result will look something like this:
const filteredTree = {
id: "1",
tag: "pending",
subtasks: [
{ id: "2", tag: "pending", subtasks: [] },
{
id: "4",
tag: "pending",
subtasks: [
{
id: "10",
tag: "pending",
subtasks: [{ id: "11", tag: "complete", subtasks: [] }]
},
{ id: "7", tag: "complete", subtasks: [] }
]
},
{ id: "5", tag: "pending", subtasks: [] },
{ id: "4", tag: "complete", subtasks: [] }
]
};
how can I achieve that?
CodePudding user response:
You could remove by checking tag
and take either the filtered subtasks
or a new object with filtered subtasks
.
const
remove = tag => ({ subtasks, ...node }) => {
subtasks = subtasks.flatMap(remove(tag));
return node.tag === tag
? subtasks
: [{ ...node, subtasks }]
},
tree = { id: "1", tag: "pending", subtasks: [ { id: "2", tag: "pending", subtasks: [] }, { id: "3", tag: "in progress", subtasks: [{ id: "4", tag: "pending", subtasks: [{ id: "6", tag: "in progress", subtasks: [{ id: "10", tag: "pending", subtasks: [{ id: "11", tag: "complete", subtasks: [] }] }] }, { id: "7", tag: "complete", subtasks: [] }] }, { id: "5", tag: "pending", subtasks: [] }] }, { id: "4", tag: "complete", subtasks: [] }] },
result = remove('in progress')(tree);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }