Search code examples
jsonangulartypescripttreeview

Search in tree structure JSON data


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?


Solution

  • 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