1

I have an array of objects that might look something like this:

{name: "A", parent: null},
{name: "B", parent: "A"},
{name: "C", parent: "B"},
{name: "D", parent: "B"},
{name: "E", parent: "A"},

here it is in a tree hierarchy:

-A
    -B
        -C
        -D
    -E   

im trying to remove all items from the array with the name of lets say "B" (this should also remove its children, so in this case items "C" and "D", however Im new to recursion and I was unable to make this work myself, could someone please show me an optimal way of doing this?

thanks to anyone willing to help in advance

  • you can do it just using `forEach` – Vivek Bani Jun 07 '21 at 15:46
  • @Goubermouche, here is a related [question](https://stackoverflow.com/questions/67825623/covert-a-array-to-a-tree-like-object-parent-child), and [answer](https://stackoverflow.com/a/67871472/12750399) – Nur Jun 07 '21 at 15:47
  • How is this being rendered? – evolutionxbox Jun 07 '21 at 15:48
  • use ```delete object.property```, it will delete that property (if it is nested object then that object too) – Muhammad Saquib Shaikh Jun 07 '21 at 15:49
  • @evolutionxbox not rendering it yet, im just trying to remove an item and all of its "children" –  Jun 07 '21 at 16:07
  • @RajdeepDebnath I understand that I have to loop through my array, however I dont know how to loop for every items possible children (and its children and so on) and then remove the desired item selected by the name property and its children –  Jun 07 '21 at 16:10
  • See my answer if you get desired result accept as correct answer – Muhammad Saquib Shaikh Jun 07 '21 at 16:13
  • This smells like a homework assignment. Is that still not-ok on stackoverflow? – Ярослав Рахматуллин Jun 07 '21 at 16:32
  • @ЯрославРахматуллин homework questions are fine usually only if an attempt has already been made to answer it. [How do I ask and answer homework questions?](https://meta.stackoverflow.com/q/334822) – evolutionxbox Jun 07 '21 at 17:20
  • @evolutionxbox I take it this message was meant for me; This isnt a homework question, im working on a project in my free time and part of it is a file system, I have attempted to make this work myself but the result was not working, and after 3 hours of trying to make it work I asked the question, however I completely understand where youre coming from –  Jun 07 '21 at 17:22
  • @Goubermouche I was replying to ЯрославРахматуллин. I didn't think the question was homework. – evolutionxbox Jun 07 '21 at 17:24
  • @evolutionxbox oh ok, my bad, for some reason I thought you made a typo and mentioned him –  Jun 07 '21 at 17:43

4 Answers4

2

var array_of_object = [
{name: "A", parent: null},
{name: "B", parent: "A"},
{name: "C", parent: "B"},
{name: "D", parent: "B"},
{name: "E", parent: "A"},
];


//returns array with updated value.
function deleteElementIncludingItsChildren(children, OriginalArray){
  return OriginalArray.filter(function(element){
    //console.log(element)
      if(element.name == children || element.parent == children) return false;
      else return element;
  });
}

console.log(deleteElementIncludingItsChildren("B", array_of_object))

Update: For removing particular node and all it's children node

var arr = [
{name: "A", parent: null},
{name: "B", parent: "A"},
{name: "C", parent: "B"},
{name: "D", parent: "B"},
{name: "E", parent: "A"},
];


function rm(node){
  var tmp = [];
  for(var i = 0; i<arr.length; i++){
    if(node == arr[i].parent)
      tmp.push(arr[i].name);
    if(node==arr[i].name){
      arr.splice(i, 1);
      i--;
    }
  }
  if(tmp.length !==0){
    tmp.forEach(function(elem){
        rm(elem);
    }); 
  }
}

rm("B")
console.log(arr)
  • 1
    this function works great, but it only "looks" 2 levels deep - so if we use the array I sent as an example it seems to work, however, when I (for example) try to delete the item named "A" it deletes everything within the first two levels (so "C" and "D" still stay in the array). Is there a way to get around this issue? –  Jun 07 '21 at 16:19
1

One way to write this is to layer it on top of another function which gathers a list of nodes capturing hierarchy of descendants. That is a straightforward recursion, and then the main function is simply a filtering:

const desc = (target, xs, node = xs .find (({name}) => name == target)) => node ? [
  node, 
  ... xs .filter (({parent}) => parent == node .name) .flatMap (({name}) => desc (name, xs))
] : []


const removeHier = (target, xs, h = desc (target, xs)) =>
  xs .filter (x => ! h.includes (x))

const records = [{name: "A", parent: null}, {name: "B", parent: "A"}, {name: "C", parent: "B"}, {name: "D", parent: "B"}, {name: "E", parent: "A"}, {name: "F", parent: "D"}]

console .log (removeHier ('B', records))
Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
0

One way to solve this:

Do a depth-first traversal of the graph and record / establish the ancestry of each element. If you are examining a leaf node and it has B as an ancestor or is B itself, it has to go.

depth-first: every time you see a child element, repeat the function / algorithm for all those children. leaf-node: an object that does not have any children.

How to establish a parent child relationship?

When you process all the elements, put each one that you have not seen before into a dictionary (aka hashmap, set, or plain object in JS) using the name of the object as the dictionary key. When you encounter something that has a given parent, just check if you have that object in the dictionary already, and add the current element as a child.

This approach may be memory intensive if the tree is very large so you may want to limit yourself to only having a single reference to a parent object from the child object instead of every parent pointing to all of it's children.

0

How to delete all nested child

function deleteAll (obj , arr){

function DeleteNode (obj){
  let no = [];
  for(let i = 0 ;i < obj.length ; i++){
    
    for(let j = 0 ;j < arr.length ; j++){

      if(arr[j].parent === obj[i]){
        no.push(arr[j].name);
        
      }
          if(obj[i] === arr[j].name){
      arr.splice(j,1);
      j--
    }
  }
  
  }
  if(no.length > 0){
    DeleteNode(no , arr)
  } 
}

DeleteNode(obj)
  return arr ;
}

// Question 
const arr = [{name: "A", parent: null},
{name: "B", parent: "A"},
{name: "C", parent: "B"},
{name: "D", parent: "B"},
{name: "E", parent: "A"}];
console.log(deleteAll (["B"] , arr))

How to Create a node

const arr = [{name: "A", parent: null},
{name: "B", parent: "A"},
{name: "C", parent: "B"},
{name: "D", parent: "B"},
{name: "E", parent: "A"}];

//first create a parent oblect 
function createTree (arr){
let parent = arr.filter((el)=>{return el.parent === null});
let children = arr.filter((el)=>{return el.parent !== null});

let tree = {};

//start



children.forEach((c)=>{
  let parent = c.name ;
  
   let step = [];
let responceFindParent = {}
function find(parent,arr){
  let a= null;
  arr.forEach((el)=>{
    if(el.name === parent){
      a= el
    } 
  })

  if(a.parent === null){
   
    step.push(a.name);
     let r ={el:a , step:step}
     responceFindParent = r
    return  ;
  }else {
    step.push(a.name)
    find(a.parent , arr)
  }
}


find(parent,arr)



let stepArr = responceFindParent.step.reverse();



function insert (tree){
  let b = stepArr[0]
  if(!(stepArr[0] in tree)){
    tree[stepArr[0]] = {}
  }
  stepArr.splice(0,1)
  
  if(stepArr . length > 0){
    insert(tree[b])
  }
}
insert (tree)
//end
  
  
})

return tree
  
}

console.log(createTree (arr))
S B RAKESH RATH
  • 443
  • 3
  • 10