如何根据给定的搜索词过滤深度未知的嵌套对象数组

How to filter array of nested objects with unknown depth based on given search term

这里有类似的答案,但我见过和测试过的所有答案都没有深入两层,所以我不认为这是一个重复的问题...我正在尝试过滤一个对象数组。它的每个对象都可以有其他未知深度的嵌套对象。对于我的数据,treeViewtreeData 的集合,treeNode(children) 将具有相同的接口。

export interface TreeView = TreeData[]

export interface TreeData {
    label: string;
    children?: TreeData[]
}
const treeData = 
[
  {label: 'obj-1', children: [ {label: 'bananas'},{label: 'apples', children: [
       {label: 'bananas',},{label: 'apples'}, {label: 'coconut',  children: [
           {label: 'bananas'},{label: 'oranges',  },
]},
]}]},
  
{label: 'obj-2', children: [ {label: 'apples'},{label: 'apples', children: [
       {label: 'oranges',},{label: 'apples'}, {label: 'coconut',  children: [
           {label: 'bananas'},{label: 'oranges', children: [
             {label: 'bananas'},{label: 'oranges',  },
] },
]},
]}]},

  {label: 'obj-3', children: [ {label: 'apples'},{label: 'mango'},{label: 'apples', children: [
       {label: 'oranges',},{label: 'apples'}, {label: 'coconut',  children: [
           {label: 'bananas'},{label: 'oranges', children: [
             {label: 'bananas'},{label: 'mango',  },
] },
]},
]}]},
]

应删除标签与搜索词不匹配的对象,如果对象有子对象 属性,请重复该过程。我一直在尝试用递归来解决这个问题。这是我的代码...

const recurse = (array, searchTerm) => {
  return array.map((element) => {
  return {...element, subElements: element.subElements.filter((subElement) => subElement.label === searchTerm)}
})
}

const filterArray = (myArray,value) => {
  for(let i = 0; i < myArray.length;i++){
    if(myArray.children){
      if(myArray[i].children){
          filterArray(myArray[i].children,value) 
        }
    }
    } 
     recurse(myArray,value)
  }


console.log(filterArray(treeData,'bananas'))

在上面的示例中,搜索 'bananas' 将根据需要过滤整个数组的深度,删除其 label prop 不等于 bananas 的任何对象;如果一个对象没有子对象,它的 label prop 是否等于搜索词,如果不是,则将其从其父数组中删除。提前致谢!

我想 return 原始 array.Only 对象的过滤版本,标签 'bananas' 应该显示在这里

我想你会想要这样的东西:

const filterByLabel = (array, searchTerm) => {
    return array.reduce((prev, curr) => {
        const children = curr.children ? filterByLabel(curr.children, searchTerm) : undefined;
        
        return curr.label === searchTerm || children?.length > 0 ? [...prev, { ...curr, children }] : prev;
    }, []);
}

filterByLabel(treeData, 'bananas');