根据自定义条件递归筛选树



我有下面的树结构。我想过滤那些版本=0.0.1的项目,因为我需要它们来根据特定的版本号构建导航。

{
title: '',
items: [
{
title: '',
path: '',
release: '0.0.1'
},
{
title: '',
path: '',
release: '0.0.2'
}
]
},
{
title: '',
items: [
{
title: '',
items: [
{
title: '',
path: '',
release: '0.0.2'
},
{
title: '',
path: '',
items: [
{
title: '',
path: '',
release: '0.0.1'
},
{
title: '',
path: '',
release: '0.0.2'
}
]
}
]
}
]
}

重点是,我需要有相同的树结构,因为在构建导航时,结构应该是一致的。

{
title: '',
items: [
{
title: '',
path: '',
release: '0.0.1'
},
]
},
{
title: '',
items: [
{
title: '',
items: [
{
title: '',
path: '',
items: [
{
title: '',
path: '',
release: '0.0.1'
},
]
}
]
}
]
}

我可以对下面的两层嵌套树执行此操作,但当涉及到items的更多嵌套层时,它似乎不起作用。

const menuToggle = (condition) => (menus) => menus
.map(menu => ({
...menu,
items: menu.items.filter(item => condition(item))
}))
.filter(menu => !isEmpty(menu.items));

您可以使用.reduce()和递归函数递归地构建新数组。如果当前对象具有items属性,则可以递归地调用menuToggle,通过过滤它及其任何子项来处理子项数组。递归函数返回后,可以使用排列语法(...(将已过滤项的更新版本推送到当前对象上,然后可以将其推送到生成的数组(acc(中。如果当前对象没有items属性,则可以检查它是否通过了条件,如果通过了,则可以将其添加到累积数组中。

参见以下示例:

const arr = [{ title: '', items: [{ title: '', path: '', release: '0.0.1' }, { title: '', path: '', release: '0.0.2' } ] }, { title: '', items: [{ title: '', items: [{ title: '', path: '', release: '0.0.2' }, { title: '', path: '', items: [{ title: '', path: '', release: '0.0.1' }, { title: '', path: '', release: '0.0.2' } ] } ] }] } ];
const menuToggle = (condition) => (menus) => {
return menus.reduce((acc, obj) => {
if(obj.items)
return [...acc, {...obj, items: menuToggle(condition)(obj.items)}];
else if(condition(obj))
return [...acc, obj];
return acc;
}, []);
}
const res = menuToggle(({release}) => release === "0.0.1")(arr);
console.log(res);

如果你还想删除产生空项目数组的对象,那么你可以对此进行额外的检查:

const arr = [{ title: '', items: [{ title: '', path: '', release: '0.0.1' }, { title: '', path: '', release: '0.0.2' } ] }, { title: '', items: [{ title: '', items: [{ title: '', path: '', release: '0.0.2' }, { title: '', path: '', items: [{ title: '', path: '', release: '0.0.1' }, { title: '', path: '', release: '0.0.2' } ] } ] }] } ];
const menuToggle = (condition) => (menus) => {
return menus.reduce((acc, obj) => {
if(obj.items) {
const items = menuToggle(condition)(obj.items);
return items.length ? [...acc, {...obj, items }] : acc;
} else if(condition(obj)) {
return [...acc, obj];
}
return acc;
}, []);
}
const res = menuToggle(({release}) => release === "0.0.1")(arr);
console.log(res);

最新更新