问题
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