0

assuming an interface such as:

interface CustomNode {
  id: string;
  children: CustomNode[];
}

If I have an object such as:

nodes: CustomNode[] = [
  {
     id: 'A',
     children: [
       {
         id: 'B',
         children: [
           {
             id: 'C',
             children: [
               {
                 id: 'D',
                 children: []
               },
               {
                 id: 'E',
                 children: []
               }
             ]
           }
         ]
       }
     ]
   }
]

how could I create a function that removes a given 'CustomNode' and its children?

I prefer a Typescript/ES6 solution, but am okay with any general solution (e.g. Typescript, Javascript, ES, dependencies such as lodash, etc)

e.g. How can I remove CustomNode with ID 'C' and its children?

nodes = removeIfExists(nodes, 'C');
removeIfExists(nodes: CustomNode[], removeId: string) {
 // ...
}
3
  • Are you trying to modify your existing data or return a copy of it? Commented Aug 6, 2020 at 20:10
  • @jcalz either way is fine. I'd prefer to return a copy but if its easier to modify the existing data, that's fine too. Commented Aug 6, 2020 at 20:12
  • did you try iteration?? I know it's not the most efficient solution Commented Aug 6, 2020 at 20:20

3 Answers 3

3

Assuming you don't want to mutate the existing array or any of its nodes, and also assuming that you are operating on an array of nodes and not one node (it looks like that's what you want), you could write it like this:

function removeIfExists(nodes: CustomNode[], removeId: string): CustomNode[] {
    return nodes.
        filter(n => n.id !== removeId).
        map(n => ({ id: n.id, children: removeIfExists(n.children, removeId) }));
}

We're removing all entries with the offending id, and then mapping the remaining nodes recursively. Let's make sure it works on your example (which I've renamed nodes):

const newNodes = removeIfExists(nodes, "C");
console.log(JSON.stringify(newNodes));
//[{ "id": "A", "children": [{ "id": "B", "children": [] }] }]

Looks good to me. Hope that helps; good luck!

Playground link to code

Sign up to request clarification or add additional context in comments.

Comments

0

An Example :

var array = [['firstItem','secondItem'],['thirdItem','fourthItem']];
array[0][1] = null;

 array = [['firstItem','secondItem'],['thirdItem','lastItem']];
array[0][1] = null;
document.getElementById('demo').innerHTML = array[0][1]
<html>
<p id="demo"></p>
</html>

Comments

0

If you want to create a new CustomNode[] the fastest way to do that is:

function removeIfExists(nodes: CustomNode[], removeId: string): CustomNode[] {
    let res: CustomNode[] = [];
    for (const node of nodes) {
        if (node.id === removeId) {
            continue;
        }
        res.push({
            id: node.id,
            children: removeIfExists(node.children, removeId),
        })
    }
    return res;
}

If you want to modify the current object you can do:

function removeIfExists(nodes: CustomNode[], removeId: string): CustomNode[] {
    let i = 0;
    while (i < nodes.length) {
        if (nodes[i].id === removeId) {
            nodes.splice(i, 1);
            continue;
        }
        removeIfExists(nodes[i].children, removeId);
        ++i;
    }
    return nodes;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.