JavaScript按用户ID合并数组,计算活动出勤总跟踪时长
解决方案:基于出勤状态与用户模式计算totalTracked总和
核心逻辑说明
要解决这个问题,关键在于正确判断用户是否出勤活动,再结合用户的全职/兼职模式累加对应时长。其中判断出勤的规则基于活动的两个字段:
isAttendanceAllOrg: true:默认全员出勤,仅usersNotAttendance中的用户视为缺勤isAttendanceAllOrg: false:默认全员缺勤,仅usersNotAttendance中的用户视为出勤
完整实现代码
// 示例用户列表(含模式信息) const users = [ { id: 'user1', mode: 'FULLTIME' }, { id: 'user2', mode: 'PARTTIME' }, { id: 'user3', mode: 'FULLTIME' } ]; // 示例活动列表 const activities = [ { id: 'act1', isAttendanceAllOrg: true, usersNotAttendance: ['user2'], minTracked: 8, minTrackedPartime: 4 }, { id: 'act2', isAttendanceAllOrg: false, usersNotAttendance: [], minTracked: 6, minTrackedPartime: 3 }, { id: 'act3', isAttendanceAllOrg: true, usersNotAttendance: ['user1', 'user3'], minTracked: 10, minTrackedPartime: 5 } ]; // 用reduce聚合计算每个用户的totalTracked const userTrackedSummary = users.reduce((summaryAcc, currentUser) => { // 计算当前用户的总tracked时长 const total = activities.reduce((sumAcc, currentActivity) => { // 判断用户是否出勤当前活动 const isAttended = currentActivity.isAttendanceAllOrg ? !currentActivity.usersNotAttendance.includes(currentUser.id) : currentActivity.usersNotAttendance.includes(currentUser.id); // 出勤则累加对应时长 if (isAttended) { return sumAcc + (currentUser.mode === 'FULLTIME' ? currentActivity.minTracked : currentActivity.minTrackedPartime); } return sumAcc; }, 0); // 内层reduce初始值必须设为0,避免累加NaN summaryAcc.push({ userId: currentUser.id, mode: currentUser.mode, totalTracked: total }); return summaryAcc; }, []); console.log(userTrackedSummary);
关键细节解析
正确判断出勤状态:
使用Array.prototype.includes()检查用户ID是否存在于usersNotAttendance数组中,这是解决你困惑的核心——直接用数组的includes方法就能准确判断用户是否在目标列表里,避免了手动遍历或错误的相等判断。嵌套reduce的使用:
- 外层reduce遍历用户列表,负责聚合每个用户的最终结果
- 内层reduce遍历活动列表,计算单个用户的总tracked时长
模式匹配累加:
根据用户的mode字段,选择累加minTracked(全职)或minTrackedPartime(兼职)
示例输出
[ { userId: 'user1', mode: 'FULLTIME', totalTracked: 8 }, { userId: 'user2', mode: 'PARTTIME', totalTracked: 5 }, { userId: 'user3', mode: 'FULLTIME', totalTracked: 8 } ]
常见错误规避
- 不要直接用
currentActivity.usersNotAttendance === currentUser.id判断,因为usersNotAttendance是数组,必须用includes方法 - 内层reduce的初始值必须设为
0,否则第一次累加会得到undefined - 确认
isAttendanceAllOrg的逻辑是否符合你的业务规则,若规则不同,只需调整isAttended的判断条件即可
内容的提问来源于stack exchange,提问作者Izlia
相关产品推荐
相关产品推荐

