Home > other >  How to iterate an Object and remove all branches filtering by a string
How to iterate an Object and remove all branches filtering by a string

Time:06-08

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')

  • Related