如何在JavaScript中找出两个对象数组的重复项并合并属性
合并两个对象数组并按Name字段处理属性
需求说明
现有两个对象数组arr_A和arr_B,需要按Name字段合并:
- 若
Name重复,生成的对象需设置CheckedOut: true, CheckedIn: true - 若
Name仅存在于其中一个数组,保留原数组的属性值,缺失的属性设为false(比如仅在arr_A的项,CheckedIn设为false;仅在arr_B的项,CheckedOut设为false)
现有代码的问题
你当前的双重循环写法存在两个核心问题:
- 重复添加元素:
arr_B的每个元素都会和arr_A的所有元素对比,导致同一个非重复Name(比如Jane)被多次添加到结果数组中 - 遗漏元素:没有处理
arr_B中独有的Name(比如Paul、Wagen),最终结果会缺失这些项
正确解法
我们可以用Map来优化查找效率,同时确保所有唯一Name都被处理:
var arr_A = [ {Name: "Smith", CheckedOut: true}, {Name: "Jane", CheckedOut: true}, ] var arr_B = [ {Name: "Smith", CheckedIn: true}, {Name: "Paul", CheckedIn: true}, {Name: "Wagen", CheckedIn: true}, ] // 将两个数组转为以Name为键的Map,方便快速查找 const mapA = new Map(arr_A.map(item => [item.Name, item])); const mapB = new Map(arr_B.map(item => [item.Name, item])); // 收集所有唯一的Name const allUniqueNames = [...new Set([...mapA.keys(), ...mapB.keys()])]; // 生成最终结果数组 const result = allUniqueNames.map(name => { const existsInA = mapA.has(name); const existsInB = mapB.has(name); return { Name: name, CheckedOut: existsInA ? mapA.get(name).CheckedOut : false, CheckedIn: existsInB ? mapB.get(name).CheckedIn : false }; }); console.log(result);
代码说明
- Map转换:把数组转成
Map后,通过Name查找元素的时间复杂度是O(1),比双重循环的O(n*m)效率更高 - 收集唯一Name:用
Set去重,确保每个Name只处理一次 - 生成结果:遍历每个唯一
Name,根据是否存在于两个数组中,设置对应的属性值,完全符合需求
运行这段代码后,就能得到你预期的结果:
[ {Name: "Smith", CheckedOut: true, CheckedIn: true}, {Name: "Jane", CheckedOut: true, CheckedIn: false}, {Name: "Paul", CheckedOut: false, CheckedIn: true}, {Name: "Wagen", CheckedOut: false, CheckedIn: true}, ]
内容的提问来源于stack exchange,提问作者anon_jj
相关产品推荐
相关产品推荐

