简体   繁体   English

在多个属性和多个值上过滤嵌套数组

[英]Filtering nested arrays on multiple properties and multiple values

I want to create flexible table filtering on user-company-roles objects in JS array. 我想在JS数组中的user-company-roles对象上创建灵活的表过滤。 User shall be able to provide filtering on multiple object properties, with multiple values, with use of AND (&&) operand when matching. 匹配时,用户应能够使用AND(&&)操作数对具有多个值的多个对象属性进行过滤。

I would appreciate tip on how to proceed implementing the logic here. 对于在这里如何继续执行逻辑的技巧,我将不胜感激。 Of course I could loop through the array and have multiple nested if-statements, but maybe there are more clean and nice approach on this? 当然,我可以遍历数组并具有多个嵌套的if语句,但是也许对此有更干净,更好的方法?

User-Company-Roles Array 用户-公司-角色数组

const userArray = [
{
    "id": "peterpan",
    "name": "Peter pan",
    "company": [
        {
            "id": "12345678",
            "name": "Company A",
            "roles": [
                "Role A",
                "Role B",
                "Role C"
            ]
        }
    ],
    "systemRoles": [
        {
            "systemName": "System A",
            "role": "Admin"
        },
        {
            "systemName": "System B",
            "role": "User"
        }
    ]
},
{
    "id": "robinhood",
    "name": "Robin Hood",
    "company": [
        {
            "id": "9876543",
            "name": "Company B",
            "roles": [
                "Role A"
            ]
        },
        {
            "id": "546372",
            "name": "Company C",
            "roles": [
                "Role A"
            ]
        }
    ],
    "systemRoles": [
        {
            "systemName": "System B",
            "role": "User"
        }
    ]
},
{
    "id": "biggiant",
    "name": "Big Giant",
    "company": [
        {
            "id": "546372",
            "name": "Company C",
            "roles": [
                "Role A"
            ]
        }
    ],
    "systemRoles": [
        {
            "systemName": "System B",
            "role": "User"
        }
    ]
}
];

Filter object 过滤对象

const filter = {
        includeUserIds: [], // filters 'user.id' that matches values in this array
        includeCompanyNames: [], // filters 'user.company.name' that matches values in this array
        includeSystemRoleNames: [], // filters 'user.systemRoles.role' that matches values in this array
        includeCompanyRoles: [], // filters 'user.company.roles' that matches values in this array
        excludeSystemRoleNames: [], // filters 'user.systemRoles.role' that **DOES NOT** match values in this array
        excludeCompanyRoles: [] // filters 'user.company.roles' that **DOES NOT** match values in this array
    }

Matching When filtering the array I want the filter to match user-objects as this (pseudo code): 匹配过滤数组时,我希望过滤器以此匹配用户对象(伪代码):

filter.includeUserIds && filter.includeCompanyNames 
    && filter.includeSystemRoleNames && filter.includeCompanyRoles 
    && !filter.excludeSystemRoleNames && !filter.excludeCompanyRoles

Example 1 : Filter users by user id: 示例1 :按用户ID过滤用户:

const filter = {
        includeUserIds: ['peterpan', 'robinhood'],
        includeCompanyNames: [],
        includeSystemRoleNames: [], 
        includeCompanyRoles: [], 
        excludeSystemRoleNames: [],
        excludeCompanyRoles: []
    }

Would return array with Peter Pan and Robin Hood users 将与Peter Pan和Robin Hood用户一起返回数组

Example 2 : Filter by company name 示例2 :按公司名称过滤

const filter = {
        includeUserIds: [],
        includeCompanyNames: ['Company C'],
        includeSystemRoleNames: [], 
        includeCompanyRoles: [], 
        excludeSystemRoleNames: [],
        excludeCompanyRoles: []
    }

Would return array with Robin Hood and Big Giant users 将与Robin Hood和Big Giant用户一起返回数组

Example 3 : Filter by company roles and system roles 示例3 :按公司角色和系统角色过滤

const filter = {
        includeUserIds: [],
        includeCompanyNames: [],
        includeSystemRoleNames: ['User'], 
        includeCompanyRoles: ['Role A'], 
        excludeSystemRoleNames: ['Admin'],
        excludeCompanyRoles: []
    }

Would return array with Robin Hood and Big Giant users 将与Robin Hood和Big Giant用户一起返回数组

I would create a decision function for each type of the filter and put it into object with same properties as filter is. 我将为每种类型的过滤器创建一个决策函数,并将其放入具有与filter相同属性的对象中。 Each function should accept 2 arguments: item of type any and filter of type string[] . 每个函数应接受2个参数: any类型的itemstring[]类型的filter So it will look like: 因此它看起来像:

const deciders = {
    includeUserIds: (item, filter) => { ... },
    includeCompanyNames: (item, filter) => { ... },
    includeSystemRoleNames: (item, filter) => { ... },
    includeCompanyRoles: (item, filter) => { ... },
    excludeSystemRoleNames: (item, filter) => { ... },
    excludeCompanyRoles: (item, filter) => { ... },
};

Then filtering is a simple filter of original array like: 然后过滤是原始数组的简单filter ,例如:

const filtered = userArray.filter(user => {
  let include = true;
  Object.keys(deciders).forEach(type => include &= deciders[type](user, filter[type]));
  return include;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM