Javascript 按特定属性值嵌套的对象的递归筛选数组

Javascript 按特定属性值嵌套的对象的递归筛选数组,javascript,arrays,recursion,filter,Javascript,Arrays,Recursion,Filter,这是我得到的数组,我的目的是过滤整个对象数组,并返回一个具有已建立名称的对象数组(即使它位于嵌套的最深级别的子对象中)。例如,如果我按“Model8”进行筛选,则函数的返回值必须是=[{name:“Model8”,键入:“file”,path:“/path/to/file”}] const arr = [ { name: "Model", type: "directory", path: "/path/to/folde

这是我得到的数组,我的目的是过滤整个对象数组,并返回一个具有已建立名称的对象数组(即使它位于嵌套的最深级别的子对象中)。例如,如果我按“Model8”进行筛选,则函数的返回值必须是=
[{name:“Model8”,键入:“file”,path:“/path/to/file”}]

const arr = [
  {
    name: "Model",
    type: "directory",
    path: "/path/to/folder",
    children: [
      {
        name: "Model1",
        type: "file",
        path: "/path/to/file",
        children: [
          {
            name: "Model2",
            type: "file",
            path: "/path/to/file",
            children: [
              {
                name: "Model3",
                type: "file",
                path: "/path/to/file",
                children: [
                  { name: "Model4", type: "file", path: "/path/to/file" },
                ],
              },
            ],
          },
        ],
      },
    ],
  },
  {
    name: "Inventory",
    type: "directory",
    path: "/path/to/folder",
    children: [{ name: "inventory.yaml", type: "file", path: "/path/to/file" }],
  },
  {
    name: "UI",
    type: "directory",
    path: "/path/to/folder",
    children: [
      { name: "elements", type: "directory", path: "/path/to/file" },
      { name: "viewmodel", type: "directory", path: "/path/to/file" },
      { name: "i18n", type: "directory", path: "/path/to/file" },
      {
        name: "index.template.html",
        type: "file",
        path: "/path/to/file",
        children: [
          {
            name: "Model5",
            type: "file",
            path: "/path/to/file",
            children: [
              {
                name: "Model6",
                type: "file",
                path: "/path/to/file",
                children: [
                  {
                    name: "Model7",
                    type: "file",
                    path: "/path/to/file",
                    children: [
                      { name: "Model8", type: "file", path: "/path/to/file" },
                    ],
                  },
                ],
              },
            ],
          },
        ],
      },
    ],
  },
  { name: "DeviceConnector", type: "directory", children: [] },
];
我提出了两种选择:

(一)

但这里的主要问题是,由于某种原因,我无法“在初始化之前访问'res'”

(二)


在这里,我不能得到低于数组的第一个迭代对象。最大深度是具有“Model3”name属性的对象。

我们可以编写一个通用函数,收集与提供的谓词匹配的所有嵌套值,然后在其顶部执行名称搜索,如下所示:

const collect=(pred)=>(xs=[])=>
xs.flatMap(x=>[
…(pred(x)?[x]:[]),
…收集(pred)(x.儿童)
])
const findByName=(目标)=>
收集(({name})=>name==target)
const arr=[{name:“Model”,type:“directory”,path:“/path/to/folder”,children:[{name:“Model”,type:“Model”,type:“file”,path:“/path/to/file”,children:[{name:“Model3”,type:“file”,path:“/path:”/to/file”,children:[{name:“Model4”,type:“file”,path:“/path:”/to/file”}]}]},{name:“库存”,类型:“目录”,路径:“/path/to/folder”,子项:[{name:“Inventory.yaml”,类型:“file”,路径:“/path/to/file”},{name:“UI”,类型:“目录”,路径:“/path/to/folder”,子项:[{name:“elements”,类型:“directory”,路径:“/path/to/file”},{name:“viewmodel”,类型:“目录”,路径:“/path/to/file”},{name:“i18n”,类型:“目录,路径:“/path/to/file”},{name:“index.template.html”,类型:“file”,路径:“/path/to/file”,子项:[{name:“Model5”,类型:“file”,路径:“/path/to/file”,子项:[{name:“Model6”,类型:“file”,路径:“/path/to/file”,子项:[{name:“Model7”,类型:“file”,路径:“/path/to/file”,子项:[{name:“Model8”,类型:“file”,路径:“/path/to/file“}]}]}]},{name:“DeviceConnector”,键入:“目录”,子项:[]}]
console.log(findByName('Model8')(arr))
function searchFilter(searchVal,arr) {
        const res = arr.filter(function filteredList(el) {
          if (el.children) {
              el.children = el.children.filter(filteredList);
          }
          if (el.name.toLowerCase().includes(searchVal.toLowerCase())) return true;
          return res;
      }); 
    }
    
    searchFilter("Model8",arr)
function searchFilter(arr, name) {
  const searchItem = arr.find((i) => i.name === name);
  if (!searchItem) {
    return arr.filter((i) => searchFilter(i.children, name));
  }
  return searchitem;
}