Reputation: 364
i need help with my little nodeJS app. i need to create a function which will delete nested groups in a tree. iv'e debugged my tree search recursion and it works great. but my delete function not deleting anything. i need to get to the parent and delete it from the array. tree looks like that:
class Group {
constructor(name, parent) {
this.name = name;
this.parent = parent || null;
this.children = [];
this.users = new users || null;
}
}
class groups {
constructor() {
this.root = new Group('root');
}
}
working tree search function (feel free to use!) and non functioning delete function
findGroupByName(name) {
if (!name)
return null;
return this._findGroupByNameInternal(this.root, name);
}
_findGroupByNameInternal(group, name) {
if (!group)
return null;
if (group.name === name)
return group;
for (const g of group.children) {
const result = this._findGroupByNameInternal(g, name);
if (!result)
continue;
return result;
}
}
removeByName(name) {
if (!this.children)
return;
const groupToRemove = this.findGroupByName(name);
if (groupToRemove) {
this.children = this.children.filter(g => g !== groupToRemove);
}
}
menu handler
function removeGroup(callback) { //need fixing
rl.question('Enter group name to delete: \n', (groupName) => {
let parentGroup = programdata.groups.findGroupByName(groupName);
programdata.groups.removeByName(groupName)
console.log(parentGroup);
callback()
})
}
function showGroups(callback) {
callback()
}
Upvotes: 0
Views: 81
Reputation: 92460
This isn't working for you because the group returned by _findGroupByNameInternal()
isn't necessarily a child of the instance you called removeByName()
on. So when you try to filter()
the instance children, it may not be there — it may be a grandchild or deeper. You need to remove the group when you find it and still know the parent. There's a lot of way to do that, but here's a simple one:
class Groups {
constructor() {
this.root = new Group('root');
}
removeByName(name){
this.root.removeByName(name)
}
}
class Group {
constructor(name, parent) {
this.name = name;
this.parent = parent || null;
this.children = [];
}
removeByName(name){
// is name in children?
let index = this.children.findIndex(g => g.name === name)
if (index > -1) {
// delete it
this.children.splice(index, 1)
console.log(`removed ${name} from ${this.name}`)
} else {
// otherwise recurse on children
this.children.forEach(child => child.removeByName(name))
}
}
}
Here's a full snippet:
class Group {
constructor(name, parent) {
this.name = name;
this.parent = parent || null;
this.children = [];
}
removeByName(name){
let index = this.children.findIndex(g => g.name === name)
if (index > -1) {
this.children.splice(index, 1)
console.log(`removed ${name} from ${this.name}`)
} else {
this.children.forEach(child => child.removeByName(name))
}
}
}
class Groups {
constructor() {
this.root = new Group('root');
}
removeByName(name){
this.root.removeByName(name)
}
}
let groups = new Groups()
// Make some nested groups
for (let j=0; j < 5; j++){
let parent = groups.root
let group = new Group(`group_${j}`, parent )
parent.children.push(group)
parent = group
for (let i=0; i < 5; i++){
let group = new Group(`group_${j}_${i}`, parent )
parent.children.push(group)
}
}
// Delete the second second of group 3 (group_3_1)
groups.removeByName('group_3_1')
// Make sure group_3_1 is gone
console.log(groups.root.children[3].children.map(c => c.name))
Upvotes: 1