JavaScript如何合并数组中同属性值对象的属性并去重
JavaScript 合并对象数组同属性项并去重解决方案
原有代码错误点
- 变量引用错误:reduce回调的当前项参数是
v,你代码里写的i.student中的i未定义,直接会触发语法报错 - 分组key逻辑错误:用
student+subject作为分组key,无法实现按「学生+班级」分组的预期效果,也没法把多科目分数聚合到同一个对象中 - 未保留同学生全科目分数:原有逻辑只会保留当前条目的科目分数,无法把同一个学生其他科目的分数合并到所有对应班级条目里
实现思路
- 先对原始数组做基础去重,过滤掉完全重复的条目
- 统计每个学生的所有科目分数,生成学生-科目分数的映射表
- 按「学生+班级」分组生成最终条目,每个条目注入该学生的所有科目分数,同时移除冗余的
subject、marks属性
完整实现代码
var input = [ { student: 'Alex', class: 'ten', subject: 'maths', marks: '85', answer: 'Moderate', percentage: '90', sports: 'good' }, { student: 'Alex', class: 'ten', subject: 'maths', marks: '85', answer: 'Moderate', percentage: '90', sports: 'good' }, { student: 'Alex', class: 'nine', subject: 'science', marks: '82', answer: 'Severe', percentage: '85', sports: 'good' }, { student: 'Alex', class: 'nine', subject: 'science', marks: '82', answer: 'Severe', percentage: '85', sports: 'good' }, { student: 'Alex', class: 'eight', subject: 'computer', marks: '90', answer: 'Extreme', percentage: '87', sports: 'good' }, { student: 'Alex', class: 'eight', subject: 'computer', marks: '90', answer: 'Extreme', percentage: '87', sports: 'good' }, { student: 'john', class: 'ten', subject: 'maths', marks: '90', answer: 'Extreme', percentage: '99', sports: 'good' }, { student: 'john', class: 'ten', subject: 'maths', marks: '90', answer: 'Extreme', percentage: '99', sports: 'good' }, { student: 'john', class: 'nine', subject: 'science', marks: '85', answer: 'Moderate', percentage: '100', sports: 'good' }, { student: 'john', class: 'nine', subject: 'science', marks: '85', answer: 'Moderate', percentage: '100', sports: 'good' }, { student: 'john', class: 'eight', subject: 'computer', marks: '87', answer: 'Extreme', percentage: '67', sports: 'good' }, { student: 'john', class: 'eight', subject: 'computer', marks: '87', answer: 'Extreme', percentage: '67', sports: 'good' }, ] // 1. 基础去重,过滤完全重复的条目 const uniqueInput = [...new Map(input.map(item => [JSON.stringify(item), item] )).values()] // 2. 统计每个学生的所有科目分数 const studentSubjectMap = uniqueInput.reduce((map, item) => { if (!map[item.student]) map[item.student] = {} map[item.student][item.subject] = item.marks return map }, {}) // 3. 按学生+班级分组生成最终结果 const result = Object.values(uniqueInput.reduce((acc, item) => { const groupKey = `${item.student}_${item.class}` if (!acc[groupKey]) { // 移除冗余的subject、marks字段,注入该学生全科目分数 const { subject, marks, ...rest } = item acc[groupKey] = { ...rest, ...studentSubjectMap[item.student] } } return acc }, {})) console.log(result)
如果需要统一同学生的answer字段取值,可在第二步生成映射表时额外存储对应字段,第三步替换即可
内容的提问来源于stack exchange,提问作者Vishnu Vedagna
相关产品推荐
相关产品推荐

