数组去重方法

✅ 一、最简单(推荐首选)

👉 使用 Set(ES6)

复制代码
const arr = [1, 2, 2, 3, 4, 4];

const result = [...new Set(arr)];

console.log(result); // [1, 2, 3, 4]

✔ 优点:

  • 写法最简洁

  • 性能好(接近 O(n))

✔ 缺点:

  • 无法处理对象去重(引用不同)

✅ 二、使用 filter

复制代码
const arr = [1, 2, 2, 3, 4, 4];

const result = arr.filter((item, index) => {
  return arr.indexOf(item) === index;
});

console.log(result);

✔ 原理:

  • 只保留第一次出现的位置

❗ 缺点:

  • 性能较差(O(n²))

✅ 三、使用 reduce

复制代码
const arr = [1, 2, 2, 3, 4, 4];

const result = arr.reduce((acc, cur) => {
  if (!acc.includes(cur)) {
    acc.push(cur);
  }
  return acc;
}, []);

console.log(result);

✔ 适合理解函数式编程


✅ 四、使用 Map(推荐处理复杂数据)

复制代码
const arr = [1, 2, 2, 3, 4, 4];

const map = new Map();
const result = [];

arr.forEach(item => {
  if (!map.has(item)) {
    map.set(item, true);
    result.push(item);
  }
});

console.log(result);

✔ 优点:

  • 性能好

  • 可扩展(对象去重)


🚀 五、对象数组去重(面试重点🔥)

👉 按某个字段去重

复制代码
const arr = [
  { id: 1, name: 'a' },
  { id: 1, name: 'b' },
  { id: 2, name: 'c' }
];

const map = new Map();

const result = arr.filter(item => {
  if (!map.has(item.id)) {
    map.set(item.id, true);
    return true;
  }
  return false;
});

console.log(result);

🧠 六、终极通用写法(封装函数)

复制代码
function unique(arr, key) {
  const map = new Map();

  return arr.filter(item => {
    const value = key ? item[key] : item;

    if (!map.has(value)) {
      map.set(value, true);
      return true;
    }
    return false;
  });
}

使用👇

复制代码
unique([1, 2, 2, 3]); 
unique([{id:1},{id:1}], 'id');

⚠️ 七、面试加分点(必须知道)

1️⃣ Set 去重不了对象

复制代码
[{a:1}, {a:1}] // ❌ 还是两个

原因:

👉 引用地址不同


2️⃣ 性能排序(面试常问)

方法 时间复杂度
Set ⭐ O(n)
Map ⭐ O(n)
filter ❌ O(n²)
includes ❌ O(n²)

3️⃣ 特殊值问题

复制代码
NaN === NaN // false

👉 但:

复制代码
new Set([NaN, NaN]) // ✅ 只保留一个

✍️ 总结一句话

👉 简单数据用 Set,复杂数据用 Map,面试优先讲这两个

相关推荐
朱涛的自习室12 分钟前
212 个需求、22 万行代码:Agent 接管开源项目的 19 天
android·前端·人工智能
aZhe的全栈知识分享15 分钟前
AI 还原 Figma 效果总达不到预期?先别急着让它写代码
前端·后端·面试
review4454316 分钟前
Codex Hooks 入门实战:生命周期事件、matcher 与5分钟跑通一个钩子
前端·agent·vibecoding
函数小陈18 分钟前
阿里云部署DSH与RAM完成运维
前端·后端
用户4993350250732 分钟前
JS 作用域劫持的死穴:动态 this 穿透,以及 AST 怎么救
前端
黑马程序员毕设33 分钟前
基于 Java 的餐饮点餐系统设计与应用报告
java·开发语言
IT_陈寒1 小时前
React的setState真是个演员,你以为它同步其实在装睡
前端·人工智能·后端
1-1=02 小时前
C# 委托与事件
开发语言·c#
Fuyo_11192 小时前
C++ 运行时多态与虚函数机制全面剖析【面试重点】
开发语言·c++·面试
孟健3 小时前
Claude Code 同需求写两版对比:装不装 frontend-design 差多远?
前端·ai编程·claude