假设有两个数组:arr1 和 arr2,并且每个数组中的元素是对象,你希望根据对象中的某个属性(比如 id),判断 arr2 中是否已经存在具有相同 id 值的对象。如果没有重复,就将 arr1 中的该对象新增到 arr2 中,否则不新增。
const arr1 = [{ id: 1, name: 'Alice' },{ id: 2, name: 'Bob' },{ id: 3, name: 'Charlie' },
];const arr2 = [{ id: 2, name: 'Bob' },{ id: 4, name: 'David' },
];
在这个例子中,arr1 中有 id 为 2 的对象,arr2 也有 id 为 2 的对象,因此不应该新增这个对象。最终结果应该是新增 id 为 1 和 3 的对象到 arr2 中。
实现方法:
方法 1:使用 Array.prototype.some
arr1.forEach(item1 => {const isDuplicate = arr2.some(item2 => item2.id === item1.id);if (!isDuplicate) {arr2.push(item1);}
});console.log(arr2);
// 输出: [
// { id: 2, name: 'Bob' },
// { id: 4, name: 'David' },
// { id: 1, name: 'Alice' },
// { id: 3, name: 'Charlie' }
// ]
方法 2:使用 Set 提高效率
当数据量较大时,使用 Set 来记录 arr2 中已存在的 id 值,可以减少 some 方法的遍历时间,提高性能。
const idSet = new Set(arr2.map(item => item.id));arr1.forEach(item => {if (!idSet.has(item.id)) {arr2.push(item);idSet.add(item.id); // 记录新增的 id,避免重复检查}
});console.log(arr2);
// 输出: [
// { id: 2, name: 'Bob' },
// { id: 4, name: 'David' },
// { id: 1, name: 'Alice' },
// { id: 3, name: 'Charlie' }
// ]
方法 3:使用 Map 进行查重和合并
如果需要对对象的其他属性进行合并或更新,可以使用 Map,它的键值对查找速度更快。
const map = new Map(arr2.map(item => [item.id, item]));arr1.forEach(item => {if (!map.has(item.id)) {map.set(item.id, item);arr2.push(item); // 新增到 arr2 中}
});console.log(arr2);
// 输出: [
// { id: 2, name: 'Bob' },
// { id: 4, name: 'David' },
// { id: 1, name: 'Alice' },
// { id: 3, name: 'Charlie' }
// ]
解释:
forEach 和 some:
遍历 arr1 中的每一个对象,使用 some 方法检查 arr2 中是否有相同 id 的对象。
如果 some 返回 false(表示没有重复),则将该对象新增到 arr2 中。
Set:
Set 用于快速记录和查找 id,避免重复。
使用 Set 能减少重复检查的时间复杂度,从而提高性能,特别是在数据量较大的情况下。
Map:
Map 用于将 id 作为键,快速查找是否已经存在对应的对象。
这种方法也可以扩展用于更新已有对象的属性,而不是简单地跳过重复对象。
总结:
当数组较小时,使用 forEach + some 是一种简单直观的方法。
当数组较大时,使用 Set 或 Map 可以显著提高查重的效率。