Javascript 按特定属性值嵌套的对象的递归筛选数组
这是我得到的数组,我的目的是过滤整个对象数组,并返回一个具有已建立名称的对象数组(即使它位于嵌套的最深级别的子对象中)。例如,如果我按“Model8”进行筛选,则函数的返回值必须是=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
[{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;
}