如何合并对象数组并去除重复项?JS/TS新手技术咨询
合并去重对象数组:Map方案完全靠谱,且正是你需要的!
嘿,作为JS/TS新手能瞄准Map这类工具来解决数组去重合并的问题,这个思路真的很赞——而且Map+reduce/filter的方案不仅正确,还特别适合你说的「复杂对象+数百条记录」的场景!
先直接回答你的核心疑问:完全可以通过Map的has()(对应你说的ContainsKey)和values()方法来实现,这其实是处理这类场景最高效的方式之一,下面给你拆解清楚:
为什么Map是最优选择?
对于复杂对象数组的去重,普通的Set没法直接用(因为对象是引用类型,即使内容相同,引用不同也会被当成不同项),而嵌套循环遍历对比的话,几百条数据虽然也能跑,但时间复杂度是O(n²),数据量再大一点就容易卡。Map的键查找是O(1)的,效率高很多,而且能灵活用对象的唯一标识来做键,完美适配复杂对象。
用Map的has()+values()实现的具体步骤
假设你的对象有一个唯一标识字段(比如id,这是最常见的情况),如果没有的话,也可以用JSON.stringify()把对象序列化成字符串当键(注意:如果对象属性顺序不固定,可能需要先排序属性再序列化,避免相同内容因为顺序不同被当成不同键)。
代码示例(TS版,JS版去掉类型即可)
type ComplexObject = { id: number; // 唯一标识字段 name: string; // 其他复杂属性... }; const mergeAndDeduplicate = (arr1: ComplexObject[], arr2: ComplexObject[]): ComplexObject[] => { // 创建一个Map,用对象的唯一id作为键,对象本身作为值 const objMap = new Map<number, ComplexObject>(); // 先把第一个数组的对象存入Map arr1.forEach(obj => { if (!objMap.has(obj.id)) { objMap.set(obj.id, obj); } }); // 遍历第二个数组,只加入Map中没有的对象 arr2.forEach(obj => { if (!objMap.has(obj.id)) { objMap.set(obj.id, obj); } }); // 把Map的values转成数组,就是去重后的合并数组 return Array.from(objMap.values()); }; // 测试用例 const arrA = [{id: 1, name: "Alice"}, {id: 2, name: "Bob"}]; const arrB = [{id: 2, name: "Bob"}, {id: 3, name: "Charlie"}]; console.log(mergeAndDeduplicate(arrA, arrB)); // 输出: [{id:1, name:"Alice"}, {id:2, name:"Bob"}, {id:3, name:"Charlie"}]
你提到的Map+reduce/filter方案是什么样的?
其实和上面的思路本质一样,只是写法更简洁。比如用reduce来构建Map:
const mergeAndDeduplicateWithReduce = (arr1: ComplexObject[], arr2: ComplexObject[]): ComplexObject[] => { const combinedArr = [...arr1, ...arr2]; const objMap = combinedArr.reduce((map, obj) => { if (!map.has(obj.id)) { map.set(obj.id, obj); } return map; }, new Map<number, ComplexObject>()); return Array.from(objMap.values()); };
而filter一般是和Map或者Set配合用在去重单个数组的场景,但合并两个数组的话,还是先合并再用reduce构建Map更直接。
注意事项
- 如果你的对象没有固定的唯一标识字段,用
JSON.stringify(obj)当键时,要确保对象的属性顺序一致,否则会出现误判。比如可以先把对象的属性按键排序再序列化:
const getUniqueKey = (obj: any) => { return JSON.stringify(Object.keys(obj).sort().reduce((sortedObj, key) => { sortedObj[key] = obj[key]; return sortedObj; }, {} as any)); };
然后把obj.id换成getUniqueKey(obj)即可。
- 数百条记录的场景下,Map的性能完全不用担心,比嵌套循环快得多,而且代码可读性也更好。
总之,你想到的这些方案都是正确且高效的,用Map的has()和values()来实现是非常直接且推荐的方式,放心用就好!
内容的提问来源于stack exchange,提问作者amidstCloud
相关产品推荐
相关产品推荐

