Reputation: 8868
I have the following model object:
const model = {
_id: '1',
children: [
{
id: '2',
isCriteria: true
},
{
id: '3',
isCriteria: true
}
]
}
PS: The depth of children is unknown, so I have to use a recursive function to navigate through it.
I want to delete specific objects fro children array based on the array of ids.
So for example if make the following call removeCriteria(model, ['2'])
, the result should be:
const model = {
_id: '1',
children: [
{
id: '2',
isCriteria: true
}
]
}
I implemented this function as follows:
function removeCriteria(node, criteria, parent = []) {
if (node.isCriteria) {
if (criteria.length && !criteria.includes(node.id)) {
parent = parent.filter(criteria => criteria.id !== node.id);
}
console.log(parent) // here the parents object is correct but it doesn't modify the original object
}
if (node.children)
for (const child of node.children) removeCriteria(child, criteria, node.children);
}
Upvotes: 0
Views: 549
Reputation: 3855
The issue is you're reassigning the variable parent
, which doesn't accomplish anything since you're not mutating the array to remove objects, and instead you're assigning it to a newly created array. I would suggest introducing a parentObj
reference to the object to which parent
belongs, so then you can set parentObj.children
to parent
and actually mutate the original object's array property:
const model = {
_id: '1',
children: [
{
id: '2',
isCriteria: true
},
{
id: '3',
isCriteria: true
}
]
};
function removeCriteria(node, criteria, parent = [], parentObj = {}) {
if (node.isCriteria) {
if (criteria.length && !criteria.includes(node.id)) {
parent = parent.filter(criteria => criteria.id !== node.id);
parentObj.children = parent;
}
console.log('parent', parent) // here the parents object is correct but it doesn't modify the original object
}
if (node.children)
for (const child of node.children) removeCriteria(child, criteria, node.children, node);
}
removeCriteria(model, ['2']);
console.log(model);
Upvotes: 1
Reputation: 781096
Assigning to parent
doesn't assign to the object property where the value came from.
You need to filter node.children
and assign back to that property.
function removeCriteria(node, criteria) {
if (criteria.length == 0) {
return;
}
if (node.children) {
node.children = node.children.filter(child => !child.isCriteria || criteria.includes(child.id));
node.children.forEach(child => removeCriteria(child, criteria));
}
}
const model = {
_id: '1',
children: [{
id: '2',
isCriteria: true
},
{
id: '3',
isCriteria: true
}
]
}
removeCriteria(model, ['2']);
console.log(model);
Upvotes: 1