You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:56:36