user15455820
user15455820

Reputation:

js remove related items from one dimensional array

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

Upvotes: 1

Views: 275

Answers (4)

Muhammad Saquib Shaikh
Muhammad Saquib Shaikh

Reputation: 298

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)

Upvotes: 2

S B RAKESH RATH
S B RAKESH RATH

Reputation: 479

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))

Upvotes: 0

Scott Sauyet
Scott Sauyet

Reputation: 50807

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))

Upvotes: 1

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.

Upvotes: 0

Related Questions