JavaScript中按参与者分组对象数组并聚合排班数据
实现方案
这个需求本质是做数据结构的反转:把原结构中「排班关联多个参与人」的一对多关系,转换成「参与人关联多个排班」的一对多关系,用中间哈希表做映射的方式实现效率最高,不需要多层嵌套循环查找。
实现代码
// 原始接口返回数据,直接替换成接口实际返回的数组即可 const rawData = [ { "participant_details":[ {"participant_id":2,"participant_name":"Bond James"}, {"participant_id":3,"participant_name":"Barkley Charles"} ], "schedule_details":{ "schedule_id":17,"schedule_name":"bug test","job_type":"Registered Nurse", "schedule_type":"Shared/Grouped Schedule","number_of_shifts":10, "start_date":"2022-05-30 23:00:00","end_date":"2022-06-03 06:00:00" } }, { "participant_details":[{"participant_id":3,"participant_name":"Barkley Charles"}], "schedule_details":{ "schedule_id":18,"schedule_name":"June Chuk Schedule","job_type":"Coordinator - Operations", "schedule_type":"Individual Schedule","number_of_shifts":6, "start_date":"2022-06-02 09:00:00","end_date":"2022-06-07 15:00:00" } }, { "participant_details":[ {"participant_id":2,"participant_name":"Bond James"}, {"participant_id":3,"participant_name":"Barkley Charles"} ], "schedule_details":{ "schedule_id":19,"schedule_name":"Grouped Re-assignment test","job_type":"People & Culture", "schedule_type":"Shared/Grouped Schedule","number_of_shifts":6, "start_date":"2022-06-04 19:00:00","end_date":"2022-06-10 02:00:00" } } ] function groupScheduleByParticipant(sourceData) { const participantMap = {}; for (const item of sourceData) { const schedule = item.schedule_details; for (const p of item.participant_details) { // 首次遍历到该参与人时初始化结构 if (!participantMap[p.participant_id]) { participantMap[p.participant_id] = { participant_id: p.participant_id, participant_name: p.participant_name, schedule_details: [] }; } // 追加当前排班到对应参与人的列表中 participantMap[p.participant_id].schedule_details.push(schedule); } } return Object.values(participantMap); } // 调用即可得到预期格式结果 const targetResult = groupScheduleByParticipant(rawData);
可选优化
如果原始数据可能出现「同一个参与人重复关联同一条排班」的异常情况,可以在push排班之前加一行去重判断,避免重复数据:
// 去重逻辑:判断当前排班是否已经在用户的排班列表里 const isExisted = participantMap[p.participant_id].schedule_details .some(s => s.schedule_id === schedule.schedule_id); if (!isExisted) { participantMap[p.participant_id].schedule_details.push(schedule); }
如果处理的数据量特别大,可以把中间存储的普通对象换成ES6的Map结构,查找性能会有小幅提升,核心逻辑不需要改动。
内容的提问来源于stack exchange,提问作者suo
相关产品推荐
相关产品推荐

