Reputation:
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
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
Reputation: 479
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))
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
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
Reputation: 7921
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