Hitting a wall with this one, thought I would post it here in case some kind soul has come across a similar one. I have some data that looks something like this:
<
Using .filter()
and making a recursive call as I described in the comment above is basically what you need. You just need to update each .children
property with the result of the recursive call before returning.
The return value is just the .length
of the resulting .children
collection, so if there's at least one, the object is kept.
var res = input.filter(function f(o) {
if (o.value.includes("Hit")) return true
if (o.children) {
return (o.children = o.children.filter(f)).length
}
})
const input = [
{
value: 'Miss1',
children: [
{ value: 'Miss2' },
{ value: 'Hit1', children: [ { value: 'Miss3' } ] }
]
},
{
value: 'Miss4',
children: [
{ value: 'Miss5' },
{ value: 'Miss6', children: [ { value: 'Hit2' } ] }
]
},
{
value: 'Miss7',
children: [
{ value: 'Miss8' },
{ value: 'Miss9', children: [ { value: 'Miss10' } ] }
]
},
{
value: 'Hit3',
children: [
{ value: 'Miss11' },
{ value: 'Miss12', children: [ { value: 'Miss13' } ] }
]
},
{
value: 'Miss14',
children: [
{ value: 'Hit4' },
{ value: 'Miss15', children: [ { value: 'Miss16' } ] }
]
},
];
var res = input.filter(function f(o) {
if (o.value.includes("Hit")) return true
if (o.children) {
return (o.children = o.children.filter(f)).length
}
})
console.log(JSON.stringify(res, null, 2))
Note that .includes()
on a String is ES7, so may need to be patched for legacy browsers. You can use the traditional .indexOf("Hit") != -1
in its place.
To not mutate the original, create a map function that copies an object and use that before the filter.
function copy(o) {
return Object.assign({}, o)
}
var res = input.map(copy).filter(function f(o) {
if (o.value.includes("Hit")) return true
if (o.children) {
return (o.children = o.children.map(copy).filter(f)).length
}
})
To really squeeze the code down, you could do this:
var res = input.filter(function f(o) {
return o.value.includes("Hit") ||
o.children && (o.children = o.children.filter(f)).length
})
Though it gets a little hard to read.