I have a tree object like below, and I need to search through it. I know there's already some answers on topics like this here, but they are, unfortunately, do not comply with my structure.
const tree = {
"28": {
"label": "lorem"
"children": {
"188": {
"label": "ipsum"
"children": {
"482": {
"label": "fish"
"children": {
"185": {
"label": "dog"
},
"289": {
"label": "cat"
}
}
}
}
}
}
},
"33": {
"label": "water"
"children": {
"95": {
"label": "fire"
"children": {
"181": {
"label": "gas"
"children": {
"100": {
"label": "station"
}
}
}
"182": {
"label": ""
"children": {
"100": {
"label": "sushi"
}
}
}
}
}
}
}
}
For example, if I'll search for 'fish', output should be like this:
{
"28": {
"label": "lorem"
"children": {
"188": {
"label": "ipsum"
"children": {
"482": {
"label": "fish"
"children": {
"185": {
"label": "dog"
},
"289": {
"label": "cat"
}
}
}
}
}
}
}
}
And if I'll search for 'dog' instead:
{
"28": {
"label": "lorem"
"children": {
"188": {
"label": "ipsum"
"children": {
"482": {
"label": "fish"
"children": {
"185": {
"label": "dog"
}
}
}
}
}
}
}
}
I tried to use these answers, but couldn't adapt them to named objects:
How to filter a tree structure while keeping the decendants of the parents that are filtered out?
children
property recursively.Array::filter()
.const search = (obj, cb) => {
let out = null;
for(const key in obj){
const item = obj[key];
if(cb(item)){
(out ??= {})[key] = item;
continue;
}
if(item.children){
const found = search(item.children, cb);
if(found){
(out ??= {})[key] = Object.assign({}, item, {children: found});
}
}
}
return out;
};
[
item => item.label === 'fish',
item => item.label === 'dog',
item => ['dog', 'station'].includes(item.label),
item => false
].forEach(cb => $pre.insertAdjacentHTML('beforeend', cb + ': ' + JSON.stringify(search(tree, cb), null, 4) + '\n'));
<script>
const tree = {
"28": {
"label": "lorem",
"children": {
"188": {
"label": "ipsum",
"children": {
"482": {
"label": "fish",
"children": {
"185": {
"label": "dog"
},
"289": {
"label": "cat"
}
}
}
}
}
}
},
"33": {
"label": "water",
"children": {
"95": {
"label": "fire",
"children": {
"181": {
"label": "gas",
"children": {
"100": {
"label": "station"
}
}
},
"182": {
"label": "",
"children": {
"100": {
"label": "sushi"
}
}
}
}
}
}
}
}
</script>
<pre id="$pre"></pre>