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

时间:2017-11-25 12:49:37

标签: javascript arrays

我想在JS数组中的user-company-roles对象上创建灵活的表过滤。用户应能够在多个对象属性上提供多个值的过滤,并在匹配时使用AND(&&)操作数。

我很感激如何在这里继续实施逻辑。当然我可以循环遍历数组并有多个嵌套的if语句,但也许有更干净,更好的方法呢?

User-Company-Roles数组

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"
        }
    ]
}
];

过滤对象

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
    }

匹配 过滤数组时,我希望过滤器匹配用户对象,如下所示(伪代码):

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

示例1 :按用户ID过滤用户:

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

将与Peter Pan和Robin Hood用户一起返回数组

示例2 :按公司名称过滤

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

将使用Robin Hood和Big Giant用户返回数组

示例3 :按公司角色和系统角色过滤

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

将使用Robin Hood和Big Giant用户返回数组

1 个答案:

答案 0 :(得分:1)

我会为每种类型的过滤器创建一个决策函数,并将其放入具有与filter相同属性的对象中。每个函数都应接受2个参数:类型为item的{​​{1}}和any类型的filter。所以它看起来像:

string[]

然后,过滤是原始数组的简单const deciders = { includeUserIds: (item, filter) => { ... }, includeCompanyNames: (item, filter) => { ... }, includeSystemRoleNames: (item, filter) => { ... }, includeCompanyRoles: (item, filter) => { ... }, excludeSystemRoleNames: (item, filter) => { ... }, excludeCompanyRoles: (item, filter) => { ... }, }; ,如:

filter