Filter an existing file tree and only return path to the endpoints

46 views Asked by At

I have a file tree with this type

interface FileTreeProps {
  name: string;
  isMat?: boolean;
  children?: FileTreeProps[];
}

After the user inputs and submits the query I want a filtered tree where the endpoints lead to the child having the type isMat. The first two children are parent folders and will never contain isMat = true. How do I go about filtering this?

I already have the code for checking similarity between two strings, and I only want to return that child if the similarity is greater than 0.25;

Example of a typical file structure (the paint brushes represent the isMat nodes): representation of the typical file tree and the object:

{
    "name": "SubtlePBR",
    "children": [
        {
            "name": "assets",
            "children": [
                {
                    "name": "minecraft",
                    "children": [
                        {
                            "name": "textures",
                            "children": [
                                {
                                    "name": "block",
                                    "children": [
                                        {
                                            "name": "acacia_leaves",
                                            "children": [],
                                            "isMat": true
                                        },
                                        {
                                            "name": "acacia_log",
                                            "children": [],
                                            "isMat": true
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}
2

There are 2 answers

1
Zoclhas On BEST ANSWER

After a few good hours I've figured it out:

  function filterTree(tree: FileTreeProps): FileTreeProps | undefined {
    const filter =
      tree.children &&
      tree.children.length > 0 &&
      (tree.children
        .map((child) => filterTree(child))
        .filter((child) => child !== undefined) as FileTreeProps[]);

    const compareQueryAndName =
      tree.name.toLowerCase().includes(query.toLowerCase()) ||
      query.toLowerCase().includes(tree.name.toLowerCase());
    if (tree.isMat && compareQueryAndName) {
      return tree;
    }

    if (!tree.isMat && tree.name !== query && filter && filter.length > 0) {
      return { name: tree.name, children: filter };
    }

    return undefined;
  }
0
Milo van der Zee On

Not really an answer because the OP did already answer his own question but I still like to share:

  export function filterDiagnosisTree(
    parent: Diagnosis, 
    filter: Diagnosis[]
  ): Diagnosis | undefined {
    const filtered: Diagnosis[] = parent.children && parent.children.length > 0
      ? parent.children.map((child) => filterDiagnosisTree(child, filter))
        .filter((child) => child !== undefined) as Diagnosis[]
      : [];
  
    if (filter.find((filterChild: Diagnosis) => filterChild.id === parent.id)) 
      return parent;
  
    if (filtered.length > 0) 
      return { ...parent, children: filtered };
  
    return undefined;
  }