【问题标题】:Filtering nested arrays on multiple properties and multiple values过滤多个属性和多个值的嵌套数组
【发布时间】:2017-11-25 12:49:37
【问题描述】:

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

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

用户-公司-角色数组

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 用户的数组

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

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

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

    然后过滤是一个简单的filter 原始数组,如:

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

    【讨论】:

    • 谢谢。您能举一个决策者功能中的逻辑示例吗?
    • 基本上很简单 (item, filter) => filter.indexOf(item) !== -1 但可能会有所不同,例如在 company 的情况下,您在对象中具有更深层次的实际价值
    猜你喜欢
    • 2020-12-02
    • 2021-08-04
    • 1970-01-01
    • 2015-11-30
    • 2020-11-07
    • 1970-01-01
    • 2017-11-03
    • 2022-08-13
    • 1970-01-01
    相关资源
    最近更新 更多