JS按email合并对象数组 仅追加attendance字段避免email重复
两个关联数组按字段合并的可迭代实现
需求说明
需要将考勤数组中的attendance字段合并到学生信息数组的对应项中,合并后email字段不重复,且函数支持后续新增学生、新增考勤数据时自动完成合并,无需修改内部逻辑。
初始数据
- 学生信息数组:
let students = [ { name: 'person1', email: 'person1@gmail.com' }, { name: 'person2', email: 'person2@gmail.com' } ]
- 考勤记录数组:
let attendances = [ { email: 'person1@gmail.com', attendance: true }, { email: 'person2@gmail.com', attendance: false } ]
预期输出
合并后返回数组结构,每个学生项包含name、email、attendance三个字段,无重复email字段,示例如下:
[ { name: 'person1', email: 'person1@gmail.com', attendance: true }, { name: 'person2', email: 'person2@gmail.com', attendance: false } ]
原有实现问题
之前编写的mergeData函数存在以下错误,导致运行不符合预期:
- 初始化的
infoMerged为空对象,不存在students、attendances属性,直接访问嵌套属性会抛出类型错误 - 循环逻辑仅做了属性存在性判断,没有编写任何实际的赋值、合并操作
- 函数调用时传参错误,未传入两个目标数组,反而传入了字符串和布尔值
- 返回值为对象结构,和预期的合并后数组结构不符
可复用实现代码
核心思路是先将考勤数组转换为以email为键的映射表,匹配时直接通过email查映射即可,无需嵌套循环,时间复杂度为O(n+m),性能更优;函数为纯函数,不会修改传入的原始数组,后续新增数据只需更新入参即可自动完成合并。
function mergeData(students, attendances) { // 构建考勤映射:key为邮箱,value为对应出勤状态 const attendanceMap = new Map() for (const record of attendances) { attendanceMap.set(record.email, record.attendance) } // 遍历学生列表,合并对应出勤状态 return students.map(student => ({ ...student, // 无匹配考勤记录时默认返回null,可根据业务需求调整默认值 attendance: attendanceMap.get(student.email) ?? null })) } // 调用示例 const mergedResult = mergeData(students, attendances) console.log(mergedResult)
后续新增学生、新增考勤数据时,直接传入更新后的数组即可,无需修改函数逻辑:
// 新增person3的数据 const updatedStudents = [ ...students, { name: 'person3', email: 'person3@gmail.com' } ] const updatedAttendances = [ ...attendances, { email: 'person3@gmail.com', attendance: true } ] // 直接调用即可得到更新后的合并结果 const newMergedResult = mergeData(updatedStudents, updatedAttendances)
内容的提问来源于stack exchange,提问作者Carmavals
相关产品推荐
相关产品推荐

