Search in tree structure JSON data

泪湿孤枕 提交于 2020-12-16 07:06:30

问题


I am building dynamic menu in a tree structure with the search option.

JSON Data looks like below:

directories = [
            {
                name: 'parent1',
                child: [{
                    name: 'child1',
                    child: [{
                        name: 'child2',
                        child: []
                    }]
                },
                {
                    name: 'child2',
                    child: []
                }]
            },
            {
                name: 'parent2',
                child: [{
                    name: 'child1',
                    child: []
                }]
            },
            {
                name: 'parent2',
                child: [{
                    name: 'child1',
                    child: []
                },
                {
                    name: 'child2',
                    child: []
                }]
            }
        ];
    }

Below code to search items in parent node level:

searchFilter(search: string) {
        console.log(search);
        this.filteredArray = this.directories.filter(item => {
            if (item.name.toString().toLowerCase().startsWith(search.toLowerCase())) {
                return true;
            }
            return false;
        }
        );
        console.log(this.filteredArray);
    }

I am calling above code on keyup event and it returns the search result on the parent node level.

Now I want to do search till the nth child. Any help?


回答1:


You need a recursive implementation for your filter, something like:

function searchFilter(search: string, directories: any[]) {
    for(let directory of directories){
        if(directory.name.toLowerCase().startsWith(search)){
            return directory;
        }
        if (directory.child !== undefined && directory.child.length > 0) {
            let childsearch = searchFilter(search, directory.child)
            if (childsearch !== undefined) {
                return childsearch
            }
        }
    }
    return undefined;
}

see on typescript playground

Another approach is possible to return every matching item in your array (act like a nth-depth filter):

function searchFilter(search: string, directories: any[], results = []) {
    for(let directory of directories){
        if(directory.name.toLowerCase().startsWith(search)){
            results.push(directory);
        }
        if (directory.child !== undefined && directory.child.length > 0) {
            let childsearch = searchFilter(search, directory.child)
            if (childsearch !== undefined) {
                results = results.concat(childsearch);
            }
        }
    }
    return results;
}

see on typescript playground




回答2:


This will look inside the whole tree and provide an array with all the corresponding results

searchFilter2(search: string, directories: any[]) {
  let results = [];
  for (let directory of directories) {
      if (directory.name.toLowerCase().startsWith(search)) {
        results.push(directory);
      }
      if (directory.child && directory.child.length > 0) {
        results = [...results, ...this.searchFilter2(search, directory.child)];
      }
  }
  return results;
}



回答3:


base on @Lejendarm answer, i change like this:

searchFilter(search: string, directories: any[]) {
      let results = [];
       for (let directory of directories) {
          if (directory.title.toLowerCase().includes(search)) {
            results.push(directory);
          } else if (directory.child && directory.child.length > 0) {
            let foundedNodes = this.searchFilter(directory.child);
            if (foundedNodes.length > 0) {
              directory.kids = foundedNodes;
              results = results.concat([directory]);
            }
          }
          
    return results;
 }


来源:https://stackoverflow.com/questions/45546157/search-in-tree-structure-json-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!