我在 React 应用程序中有一个模式,它呈现一个带有嵌套值列表和搜索栏的项目列表。当用户在搜索栏中输入内容时,我需要能够将该输入与列表中的项目相匹配,并显示该匹配的确切路径。
例如,我的数据如下:
const dataList = [
{
label: 'Foo',
value: 'foo',
subItems: [
{
label: 'Sub bar 1',
value: 'sub_bar_1',
subItems: [
{ label: 'Nested baz 1', value: 'nested_baz_1' },
{ label: 'Nested baz 2', value: 'nested_baz_2' },
],
},
{
label: 'Sub bar 2',
value: 'sub_bar_2',
},
],
},
{
label: 'Bar',
value: 'bar',
subItems: [],
},
];
并且给定查询字符串,
Nested baz 2
,我期望输出为:
const filteredList = [{
label: 'Foo',
value: 'foo',
subItems: [
{
label: 'Sub bar 1',
value: 'sub_bar_1',
subItems: [
{ label: 'Nested baz 2', value: 'nested_baz_2' },
],
},
],
}];
我尝试了递归函数和老式
for
循环的多次迭代,但没有任何东西可以给我与我的查询字符串匹配的对象的确切路径。
在当前的实现中我可以改变什么以获得所需的输出吗?
const filterItems = (
options: Option[],
query: string
): Option[] => {
return options.filter((option) => {
if (option.label.toLowerCase().includes(query.toLowerCase())) {
return true;
}
if (option.subItems) {
return filterCategories(option.subItems, query).length > 0;
}
return false;
});
};
const filteredItems = useMemo(() => {
return filterItems(options, query);
}, [options, query]);
您可以通过以下方式实现这一目标
const filterDataList = (dataList, searchTerm) => {
return dataList
.map(item => {
if (item.label.includes(searchTerm)) {
return item;
}
if (item.subItems && item.subItems.length > 0) {
const filteredSubItems = filterDataList(item.subItems, searchTerm);
if (filteredSubItems.length > 0) {
return { ...item, subItems: filteredSubItems };
}
}
return null;
})
.filter(item => item !== null);
}
const searchTerm = 'Nested baz 2';
const filteredList = filterDataList(dataList, searchTerm);