How to remove an object (element) based on the property from nested obj. For example, I need to remove all objects with type: 'green' from obj tree if obj has children it will be also removed.
const obj = {
id: '01',
children: [
{
id: '02',
type: 'green',
children: [
{
id: '03',
type: 'black',
children: [],
},
{
id: '04',
type: 'green',
children: [
{
id: '05',
type: 'white',
children: [],
}
],
}
],
},
{
id: '06',
type: 'black',
children: [
{
id: '07',
type: 'green',
children: [],
},
{
id: '08',
type: 'white',
children: [
{
id: '09',
type: 'green',
children: [],
}
],
}
],
},
]
}
// expected result (if remove type: "green")
const expectedObj = {
id: '01',
type: 'orange',
children: [
{
id: '06',
type: 'black',
children: [
{
id: '08',
type: 'white',
children: [],
}
],
},
]
}
What I am trying to do
let match = false
const removeByType = (data, type) => {
match = data.some(d => d.type == type)
if (match) {
data = data.filter(d => d.type !== type)
} else {
data.forEach(d => {
d.children = removeByType(d.children, type)
})
}
return data
}
let data = obj.children
console.dir(removeByType(data, 'black'), { depth: null })
but { id: '03', type: 'black', children: [] } is still in the object tree
CodePudding user response:
You were close, just missing that each instance was an array that you had to map
through
const removeByType = (data, type) => {
data = data.filter(d => d.type !== type)
data = data.map(d => {
d.children = removeByType(d.children, type);
return d;
})
return data
}
const obj = {
id: '01',
children: [{
id: '02',
type: 'green',
children: [{
id: '03',
type: 'black',
children: [],
},
{
id: '04',
type: 'green',
children: [{
id: '05',
type: 'white',
children: [],
}],
}
],
},
{
id: '06',
type: 'black',
children: [{
id: '07',
type: 'green',
children: [],
},
{
id: '08',
type: 'white',
children: [{
id: '09',
type: 'green',
children: [],
}],
}
],
},
]
}
const removeByType = (data, type) => {
data = data.filter(d => d.type !== type)
data = data.map(d => {
d.children = removeByType(d.children, type);
return d;
})
return data
}
console.dir(removeByType(obj.children, 'black'), {
depth: null
})
CodePudding user response:
I've done that..
const removeByType = (data, type) =>
{
for (let i=data.children.length;--i>=0;)
{
if ( data.children[i].type===type) data.children.splice(i,1)
else removeByType (data.children[i], type)
}
return data // just for chaining ... ?
}
usage:
const my_obj =
{ id: '01', type: 'orange', children: // stay
[ { id: '02', type: 'green', children: // - green
[ { id: '03', type: 'black', children: [] } // -
, { id: '04', type: 'green', children: // -
[ { id: '05', type: 'white', children: [] } // -
]
} ] }
, { id: '06', type: 'black', children: // stay
[ { id: '07', type: 'green', children: [] } // - green
, { id: '08', type: 'white', children: // stay
[ { id: '09', type: 'green', children: [] } // - green
]
} ] } ] }
const removeByType = (data, type) =>
{
for (let i=data.children.length;--i>=0;)
{
if ( data.children[i].type===type) data.children.splice(i,1)
else removeByType (data.children[i], type)
}
return data
}
console.log( removeByType(my_obj, 'green') )
// my_obj is now updated...
console.log( my_obj )
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}