JavaScript中基于公共匹配属性合并部分信息对象数组的实现方案
问题根因
你当前的写法有两个核心逻辑漏洞,完全无法触发匹配判断:
Object.keys(innerItem)返回的是对象所有键组成的数组,把这个数组直接当属性名去取item的值,永远会得到undefined,两侧的比对值根本取不到有效内容- 嵌套使用两层
map没有设计返回值,既没有把匹配到的两个对象做字段拼接,也没有把结果输出到最终的数组里
可落地实现方案
核心匹配逻辑完全按照你的需求设计:不写死固定匹配字段,自动识别两个对象的共有键,只要共有键对应的取值完全一致,就判定为同一条需要合并的记录,避免硬编码name/date这类固定匹配字段。
实现步骤
- 封装通用的匹配判断函数,自动提取两个对象的共有键,跳过嵌套对象、数组这类复杂类型的比对(匹配当前示例的基本类型值场景),只要所有共有基本类型键的取值完全一致,就判定匹配成功
- 遍历第一个数组的每一条记录,从第二个数组中找到匹配的对应记录
- 把两个匹配到的记录做字段展开合并,保留所有属性得到最终对象
完整可运行代码
// 匹配判断工具函数 function isRecordMatch(baseRecord, targetRecord) { // 提取两个记录的所有共有键 const commonKeys = Object.keys(baseRecord).filter(key => Object.hasOwn(targetRecord, key)); // 校验所有共有键的取值是否完全一致,跳过复杂类型值的比对 return commonKeys.every(key => { const baseVal = baseRecord[key]; const targetVal = targetRecord[key]; // 嵌套对象/数组类型的值跳过比对,避免复杂的递归校验 if (typeof baseVal === 'object' || typeof targetVal === 'object') return true; return baseVal === targetVal; }); } // 执行合并逻辑 const final = arr1.map(baseItem => { // 在arr2中找到和当前记录匹配的目标项 const matchedItem = arr2.find(targetItem => isRecordMatch(baseItem, targetItem)); // 匹配到就合并两个对象的所有字段,未匹配到就保留原记录 return matchedItem ? {...baseItem, ...matchedItem} : baseItem; });
效果验证
运行上述代码后,得到的final数组结构和你预期的结果完全一致:
- 第一项自动通过共有键
name、date的匹配值关联arr2里Rohan的成绩信息,合并为完整记录 - 第二项自动通过共有键
surname、date的匹配值关联arr2里Kohli的成绩信息,合并为完整记录 - 第三项自动通过共有键
date的匹配值关联arr2里Sam的成绩信息,合并为完整记录
补充说明:如果后续遇到共有键数量太少(比如单靠date匹配到不同考生的记录)导致误匹配的情况,可以调整isRecordMatch函数,增加共有键匹配数量的阈值要求(比如至少2个不同字段的值一致才判定匹配),进一步提升匹配精度
内容的提问来源于stack exchange,提问作者Akshay
相关产品推荐
相关产品推荐

