[英]Filter array of object with sub objects
抱歉,如果已经有答案,我一直无法找到对我有用的答案。
我为 React 定义了一个菜单系统,其中信息存储在一个对象数组中。 每个 object 都有子项(另一个数组中的对象)的可能性,我正在寻找过滤整个菜单的值。
Menu Object
[
{
"key": "Dashboard",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"title": "Dashboard",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/",
"children": "Dashboard"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Clients",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"isSubMenu": true,
"title": "Clients",
"submenus": [
{
"key": "Clients.Add",
"title": "Create Client",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Clients/create",
"children": "Create Client"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Clients.List",
"title": "List Clients",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Clients/",
"children": "List Clients"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Clients.Search",
"title": "Search Clients",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Clients/search",
"children": "Search Clients"
},
"_owner": null,
"_store": {}
}
}
]
},
{
"key": "Contractors",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"isSubMenu": true,
"title": "Contractors",
"submenus": [
{
"key": "Contractors.Add",
"title": "Create Contractor",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Contractors/create",
"children": "Create Contractor"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Contractors.List",
"title": "List Contractors",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Contractors/",
"children": "List Contractors"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Contractors.Search",
"title": "Search Contractors",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Contractors/search",
"children": "Search Contractors"
},
"_owner": null,
"_store": {}
}
}
]
},
{
"key": "Jobs",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"isSubMenu": true,
"title": "Jobs",
"submenus": [
{
"key": "Jobs.Add",
"title": "Create Job",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Jobs/create",
"children": "Create Job"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Jobs.List",
"title": "List Jobs",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Jobs/",
"children": "List Jobs"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Jobs.Search",
"title": "Search Jobs",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Jobs/search",
"children": "Search Jobs"
},
"_owner": null,
"_store": {}
}
}
]
},
{
"isDivider": true
},
{
"key": "Config",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"isSubMenu": true,
"title": "Configuration",
"submenus": [
{
"key": "Config.Category.Add",
"title": "Create Category",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Category/create",
"children": "Create Category"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Config.Category.List",
"title": "List Categories",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Category/",
"children": "List Categories"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Config.Specialist.Add",
"title": "Create Specialist",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Specialist/create",
"children": "Create Specialist"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Config.Specialist.List",
"title": "List Specialists",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Specialist/",
"children": "List Specialists"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Config.Status.Add",
"title": "Create Status",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Status/create",
"children": "Create Status"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Config.Status.List",
"title": "List Statuses",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Status/",
"children": "List Statuses"
},
"_owner": null,
"_store": {}
}
}
]
},
{
"key": "UserManagement",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"isSubMenu": true,
"title": "User Management",
"submenus": [
{
"key": "UserManagement.Add",
"title": "Create User",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/UserManagement/create",
"children": "Create User"
},
"_owner": null,
"_store": {}
}
},
{
"key": "UserManagement.List",
"title": "List Users",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/UserManagement/",
"children": "List Users"
},
"_owner": null,
"_store": {}
}
}
]
},
{
"isDivider": true
},
{
"key": "LockScreen",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"title": "Lock Screen",
"component": "Lock Screen"
}
]
因此,如果我要针对值“列表”的标题过滤它,它应该返回
[
{
"key": "Clients",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"isSubMenu": true,
"title": "Clients",
"submenus": [
{
"key": "Clients.List",
"title": "List Clients",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Clients/",
"children": "List Clients"
},
"_owner": null,
"_store": {}
}
}
]
},
{
"key": "Contractors",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"isSubMenu": true,
"title": "Contractors",
"submenus": [
{
"key": "Contractors.List",
"title": "List Contractors",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Contractors/",
"children": "List Contractors"
},
"_owner": null,
"_store": {}
}
},
]
},
{
"key": "Jobs",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"isSubMenu": true,
"title": "Jobs",
"submenus": [
{
"key": "Jobs.List",
"title": "List Jobs",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Jobs/",
"children": "List Jobs"
},
"_owner": null,
"_store": {}
}
},
]
},
{
"key": "Config",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"isSubMenu": true,
"title": "Configuration",
"submenus": [
{
"key": "Config.Category.List",
"title": "List Categories",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Category/",
"children": "List Categories"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Config.Specialist.List",
"title": "List Specialists",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Specialist/",
"children": "List Specialists"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Config.Status.List",
"title": "List Statuses",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Status/",
"children": "List Statuses"
},
"_owner": null,
"_store": {}
}
}
]
},
{
"key": "UserManagement",
"icon": {
"type": {},
"key": null,
"ref": null,
"props": {},
"_owner": null,
"_store": {}
},
"isSubMenu": true,
"title": "User Management",
"submenus": [
{
"key": "UserManagement.List",
"title": "List Users",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/UserManagement/",
"children": "List Users"
},
"_owner": null,
"_store": {}
}
}
]
}
]
或者它应该返回
[
{
"key": "Clients.List",
"title": "List Clients",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Clients/",
"children": "List Clients"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Contractors.List",
"title": "List Contractors",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Contractors/",
"children": "List Contractors"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Jobs.List",
"title": "List Jobs",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Jobs/",
"children": "List Jobs"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Config.Category.List",
"title": "List Categories",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Category/",
"children": "List Categories"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Config.Specialist.List",
"title": "List Specialists",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Specialist/",
"children": "List Specialists"
},
"_owner": null,
"_store": {}
}
},
{
"key": "Config.Status.List",
"title": "List Statuses",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/Config/Status/",
"children": "List Statuses"
},
"_owner": null,
"_store": {}
}
},
{
"key": "UserManagement.List",
"title": "List Users",
"component": {
"type": {},
"key": null,
"ref": null,
"props": {
"to": "/admin/UserManagement/",
"children": "List Users"
},
"_owner": null,
"_store": {}
}
}
]
目前我有以下适用于第一级对象的内容,但子菜单全部返回:
const MenuSearch = (value) => {
const SearchTerm = value.toLowerCase();
console.log(SearchTerm, MenuItems);
if (!value || value.length < 1){
// show all menu items
SetMenuItemsFiltered(MenuItems);
} else {
let temp = [...MenuItems];
SetMenuItemsFiltered(temp.filter((MenuItem) => {
if (!MenuItem.isSubMenu && !MenuItem.isDivider){
return MenuItem.title.toLowerCase().includes(SearchTerm);
} else if (MenuItem.isSubMenu){
return MenuItem.submenus.filter((SubMenuItem) => {
const SubMenuItemLabel = SubMenuItem.title.toLowerCase();
console.log(SubMenuItemLabel, SearchTerm, SubMenuItemLabel.includes(SearchTerm))
return SubMenuItemLabel.includes(SearchTerm.toLowerCase());
})
}
}));
}
}
. ~
.~value.length
中的 ~ 只是我说“不要从 -1 开始并认为它是 0”的首选方式
const MenuSearch = (value) => {
const searchWord = value.toLowerCase();
if (!value || !~value.length) {
// early return.
return SetMenuItemsFiltered(MenuItems);
}
const result = data.reduce((prev, curr) => {
const title = curr.title?.toLowerCase();
if (!curr.submenus && !curr.isDivider) {
if (title.includes(searchWord)) {
return prev.concat(curr);
}
}
if (curr.isSubMenu) {
return prev.concat(
curr.submenus.filter((item) =>
item.title.toLowerCase().includes(searchWord)
),
);
}
return prev;
}, []);
SetMenuItemsFiltered(result);
};
我想这就是你要找的:
const objectsFilter = require("objectsfilter");
const data = require("./data.json");
const MenuSearch = (value) => {
const searchWord = value.toLowerCase();
if (!value || !~value.length) {
// early return.
return SetMenuItemsFiltered(MenuItems);
}
const result = data.reduce((prev, curr) => {
const title = curr.title?.toLowerCase();
if (!curr.submenus && !curr.isDivider) {
if (title.includes(searchWord)) {
return prev.concat(curr);
}
}
if (curr.isSubMenu) {
const submenus = [];
objectsFilter.objectsForEach(curr, (currentItem, key) => {
if (key === "submenus") {
submenus.push(
currentItem.filter((item) =>
item.title.toLowerCase().includes(searchWord)
),
);
}
});
return prev.concat({
...curr,
submenus,
});
}
return prev;
}, []);
SetMenuItemsFiltered(result);
};
问题是您正在过滤MenuItem.submenus
但不存储过滤后的值。 相反,您只是返回整个MenuItem.submenu
所以应该是
MenuItem.submenus= MenuItem.submenus.filter((SubMenuItem) => {
const SubMenuItemLabel = SubMenuItem.title.toLowerCase();
return SubMenuItemLabel.includes(SearchTerm.toLowerCase());
})
如果MenuItem.submenus.length>0
则返回 true。
所以最终代码是
temp.filter((MenuItem) => {
if (!MenuItem.isSubMenu && !MenuItem.isDivider){
return MenuItem.title.toLowerCase().includes(SearchTerm);
} else if (MenuItem.isSubMenu){
MenuItem.submenus= MenuItem.submenus.filter((SubMenuItem) => {
const SubMenuItemLabel = SubMenuItem.title.toLowerCase();
console.log(SubMenuItemLabel, SearchTerm,
SubMenuItemLabel.includes(SearchTerm))
return SubMenuItemLabel.includes(SearchTerm.toLowerCase());
})
return MenuItem.submenus.length;
}
})
我最终对此采取了不同的方法,而不是返回过滤器,我会使用过滤器创建一个新的匹配对象数组。 我已经在这里发布了答案,但会继续检查是否有人提出更好的解决方案。
const MenuSearch = (value) => {
const SearchTerm = value.toLowerCase();
if (!value || value.length < 1){
// show all menu items
SetMenuItemsFiltered(MenuItems);
} else {
let FilteredItems = [];
// filter the data
MenuItems.filter((MenuItem) => {
if (!MenuItem.isSubMenu && !MenuItem.isDivider){
if (MenuItem.title.toLowerCase().includes(SearchTerm)){
FilteredItems.push(MenuItem);
}
//return MenuItem.title.toLowerCase().includes(SearchTerm);
} else if (MenuItem.isSubMenu){
MenuItem.submenus.filter((SubMenuItem) => {
const SubMenuItemLabel = SubMenuItem.title.toLowerCase();
// return SubMenuItemLabel.includes(SearchTerm);
if (SubMenuItemLabel.includes(SearchTerm)){
FilteredItems.push(SubMenuItem);
}
})
}
});
SetMenuItemsFiltered(FilteredItems);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.