如何编写函数将含多角色的用户对象数组按roles字段分组?
按角色分组用户(多角色用户归入对应所有分组)
这是一个很常见的分组需求,我们可以通过数组的reduce方法结合遍历角色数组来轻松实现。下面是具体的实现方案:
核心实现函数
function groupUsersByRoles(userData) { return userData.users.reduce((groups, user) => { // 遍历当前用户的每一个角色 user.roles.forEach(role => { // 如果该角色的分组尚未创建,先初始化空数组 if (!groups[role]) { groups[role] = []; } // 将当前用户添加到对应角色的分组中 groups[role].push(user); }); return groups; }, {}); // 初始累积值为一个空对象,用于存储分组结果 }
代码说明
Array.reduce:用来累积生成最终的分组对象,初始值设为空对象{}。- 遍历角色数组:对每个用户,循环处理他拥有的每一个角色,确保用户被添加到所有对应角色的分组里。
- 初始化分组数组:如果当前角色还没有对应的分组数组,先创建一个空数组,避免后续
push操作报错。 - 添加用户到分组:把当前用户对象放入对应角色的数组中。
测试示例
将你的输入数据传入函数,即可得到期望的分组结果:
const input = { users: [ { firstName: 'Will', lastName: 'Jacob', email: 'sample@sample.com', _id: '5e324187b5fdf167a91dfdbb', roles: [ 'ward', 'hospital', 'hr' ] }, { firstName: 'Theatre', lastName: 'Manager', email: 'sample@sample.com', _id: '5e3cf2f0c631a8788be59fc4', roles: [ 'ward' ] }, { firstName: 'Cinema', lastName: 'Manager', email: 'sample@sample.com', _id: '5e3cf62cc631a8788be59fc5', roles: ['hospital', 'hr' ] }, { firstName: 'Cinema2', lastName: 'Manager', email: 'sample@sample.com', _id: '5e3cf62cc631a8788be59fc5', roles: ['ward', 'hr' ] }, { firstName: 'Cinema3', lastName: 'Manager', email: 'sample@sample.com', _id: '5e3cf62cc631a8788be59fc5', roles: ['hospital', 'hr' ] }, { firstName: 'Cinema4', lastName: 'Manager', email: 'sample@sample.com', _id: '5e3cf62cc631a8788be59fc5', roles: [ 'ward', 'hospital', 'hr' ] } ]}; const groupedUsers = groupUsersByRoles(input); console.log(groupedUsers);
可选优化:深拷贝用户对象
如果后续需要修改分组中的用户数据,且不想影响原始用户数组的内容,可以对用户对象进行深拷贝后再添加到分组中:
function groupUsersByRoles(userData) { return userData.users.reduce((groups, user) => { user.roles.forEach(role => { if (!groups[role]) { groups[role] = []; } // 使用扩展运算符浅拷贝用户对象(适合无嵌套对象的场景) groups[role].push({ ...user }); // 如果用户对象有嵌套结构,可改用JSON深拷贝: // groups[role].push(JSON.parse(JSON.stringify(user))); }); return groups; }, {}); }
这个实现方案简洁高效,时间复杂度为O(n*m)(n为用户数量,m为平均每个用户的角色数),能很好地处理你提供的场景需求。
内容的提问来源于stack exchange,提问作者Tech Nerd
相关产品推荐
相关产品推荐

