ES6移除对象数组重复项及合并对象数组的最优方法问询
嘿,这两个问题都是前端开发里经常碰到的数组处理需求,我用ES6的特性给你整理了优雅的解决方案👇
问题1:如何使用ES6移除对象数组中的重复项?
移除对象数组的重复项分两种常见场景,我分别给你实用方案:
场景1:根据对象的某个唯一属性去重(比如id、name)
这是最常见的情况——比如接口返回的数据里,有多个id相同的对象,我们只需要保留唯一的那一个。用ES6的Map或者filter配合findIndex都能搞定:
const arr = [ { id: 1, name: 'Apple' }, { id: 2, name: 'Banana' }, { id: 1, name: 'Apple' } ]; // 方法1:高效的Map存储法(推荐,时间复杂度O(n)) const uniqueMap = new Map(); arr.forEach(item => { if (!uniqueMap.has(item.id)) { uniqueMap.set(item.id, item); } }); const uniqueArr = [...uniqueMap.values()]; // 方法2:filter+findIndex写法,代码更简洁 const uniqueArr = arr.filter((item, index, self) => index === self.findIndex(t => t.id === item.id) );
场景2:整个对象完全相同时去重
如果要求两个对象的所有键值对完全一致才算重复,可以把对象转成字符串来做判断:
const arr = [ { name: 'Apple', price: 5 }, { name: 'Banana', price: 3 }, { name: 'Apple', price: 5 } ]; const uniqueArr = [...new Set(arr.map(item => JSON.stringify(item)))].map(str => JSON.parse(str));
⚠️ 注意:这种方式对对象的键顺序敏感,如果两个对象键顺序不同但值相同,会被当成不同项。要是在意这点,可以先把对象的键排序后再转字符串。
问题2:合并itemsA与itemsB并符合指定规则
先明确核心规则:source为'STAPLE'的项不能重复,其他source的项可以保留重复,最终要得到11项(6+7-2,说明有2个重复的STAPLE项)。
最优实现思路是用Set跟踪已加入的STAPLE项的唯一标识(这里假设用name作为判断重复的依据,你可以换成实际业务里的唯一键,比如id),然后用reduce遍历合并数组:
// 模拟符合条件的示例数据 const itemsA = [ { source: 'STAPLE', name: 'Rice' }, { source: 'STAPLE', name: 'Flour' }, { source: 'USER', name: 'Ball' }, { source: 'USER', name: 'Pen' }, { source: 'STAPLE', name: 'Sugar' }, { source: 'USER', name: 'Book' } ]; const itemsB = [ { source: 'STAPLE', name: 'Rice' }, // 重复的STAPLE项 { source: 'STAPLE', name: 'Salt' }, { source: 'USER', name: 'Ball' }, // 可重复的USER项 { source: 'USER', name: 'Bag' }, { source: 'STAPLE', name: 'Flour' }, // 重复的STAPLE项 { source: 'USER', name: 'Notebook' }, { source: 'USER', name: 'Pencil' } ]; // 合并逻辑 const stapleKeys = new Set(); const mergedList = [...itemsA, ...itemsB].reduce((acc, item) => { if (item.source === 'STAPLE') { // 只保留未出现过的STAPLE项 if (!stapleKeys.has(item.name)) { stapleKeys.add(item.name); acc.push(item); } } else { // 非STAPLE项直接加入 acc.push(item); } return acc; }, []); console.log(mergedList.length); // 输出11,完全符合要求
这个方案的优势:
- 仅遍历一次数组,时间复杂度O(n),效率拉满
- 用Set做存在性判断,查找速度是O(1)
- 逻辑清晰易维护,后续改规则只需要调整Set存储的键就行
内容的提问来源于stack exchange,提问作者aps5842
相关产品推荐
相关产品推荐

