Let's say I have an object with this interface:
export interface Role {
children: Role[];
name: string;
}
and I want to filter it by a string, iterate it without knowing how deep it can get, and if a children in, let's say, iteration 4, has in it's name part of that string, keep that child with all it's parents upwards.
CodePudding user response:
Here's a straightforward solution that should account for any number of children or siblings.
Given the input of a role, filterRole
will return the Role tree/object without child nodes/child node paths that don't pass the filter. Consequently, it shows long/deep paths where innermost children do pass the filter but parents do not.
interface Role {
children: Role[];
name: string;
}
// Build the Role tree
const invalidChildNode = {name: 'this should be ignored', children: []}
const childNode = {name: 'child', children: []}
const parentNode = {name: 'parent', children: [childNode, invalidChildNode]};
const root = {name: 'root', children: [parentNode]};
/** filterRole takes in a single Role and strips it of all children/paths that do not satisfy the filter at any point. */
const filterRole = (role: Role, filter: string) => {
let children = role.children;
if (children.length > 0) {
children = role.children.map(childRole => filterRole(childRole, filter)).filter(r => r !== null) as Role[];
}
// We rebuild this role node with the correct children that recursively passed the filter, either by themselves or within their subtrees.
return role.name.includes(filter) || children.length > 0 ? {
...role,
children
}: null;
}
console.log(filterRole(root, 'child')) // this should return the full tree without the "this should be ignored" node.
console.log('-----------');
console.log(filterRole(root, 'ignored')) // this should return the full tree without the "child" node.
console.log('-----------');
console.log(filterRole(root, 'parent')) // this should only return up to the parent node.
Typescript playground to see it in effect
CodePudding user response:
Sth like that?
const parent = {children:{children:{children:{children:null,name:'d'},name:'c'},name:'b'},name:'a'}
function findName(baseParents,person,searchedName)
{
if(person&&person.name!=searchedName)
return findName(baseParents,person.children,searchedName)
return {baseParents,person}
}
findName(parent,parent,'c')