JavaScript数组去重的多种实现方式

前言

在前端开发中,数组去重是一个常见的需求。无论是处理用户数据、API响应还是进行数据清洗,我们都需要掌握去重方法。本文将详细介绍JavaScript中数组去重的多种实现方式。

1. 使用Set数据结构(ES6推荐)

javascript

ini 复制代码
const arr = [1, 2, 2, 3, 4, 4, 5, 'a', 'a'];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4, 5, "a"]

Set 是 ES6 引入的一种新的数据结构,它类似于数组,但是成员的值都是唯一的,没有重复的值。

javascript

scss 复制代码
// Set的基本使用
const arr1 = new Set()
arr1.add(1)
arr1.add(2)
arr1.add(3)
arr1.add(1)  // 重复添加
console.log(arr1)  // {1, 2, 3} - 重复的自动过滤

2. 使用filter + indexOf方法

javascript

ini 复制代码
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(uniqueArr); // [1, 2, 3, 4, 5]

这里利用了filter方法和indexOf方法的特性:

  • filter会遍历数组,将符合条件的元素组成新数组返回
  • indexOf返回元素在数组中第一次出现的位置索引
  • 只有当元素第一次出现时的索引与当前索引相等时,才保留该元素

3. 使用reduce方法

javascript

ini 复制代码
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.reduce((acc, current) => {
  return acc.includes(current) ? acc : [...acc, current];
}, []);
console.log(uniqueArr); // [1, 2, 3, 4, 5]

reduce方法通过累积器遍历数组,检查当前元素是否已存在于累积器中,不存在则添加。

4. 使用forEach + includes方法

javascript

ini 复制代码
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [];
arr.forEach(item => {
  if (!uniqueArr.includes(item)) {
    uniqueArr.push(item);
  }
});
console.log(uniqueArr); // [1, 2, 3, 4, 5]

这种方法思路直观:

  • 创建空数组存储结果
  • 遍历原数组,检查元素是否已存在
  • 不存在则添加到结果数组

方法对比

  • forEach:遍历数组执行操作,不关心返回值
  • map:将数组转换为新数组(1:1映射)
  • filter:根据条件筛选数组元素

5. 对象数组去重(基于特定属性)

实际开发中,我们经常需要根据对象属性去重:

javascript

ini 复制代码
const users = [
  {id: 1, name: 'Alice'},
  {id: 2, name: 'Bob'},
  {id: 1, name: 'Alice'},  // 重复
  {id: 3, name: 'Charlie'}
];

// 方法1:使用Map(推荐)
const uniqueUsers = [...new Map(users.map(item => [item.id, item])).values()];

// 方法2:使用reduce
const uniqueUsers2 = users.reduce((acc, current) => {
  const exists = acc.find(item => item.id === current.id);
  return exists ? acc : [...acc, current];
}, []);

console.log(uniqueUsers); // 基于id去重后的数组

Map方法利用键的唯一性,将对象ID作为键,对象本身作为值,最后通过values()获取去重后的对象。

6. 复杂数据类型去重

对于包含对象、数组等复杂数据类型的数组:

javascript

ini 复制代码
const complexArr = [{a:1}, {a:1}, [1,2], [1,2], 'hello', 'hello'];

const uniqueComplex = complexArr.reduce((acc, current) => {
  const isDuplicate = acc.some(item =>
    JSON.stringify(item) === JSON.stringify(current)
  );
  return isDuplicate ? acc : [...acc, current];
}, []);

console.log(uniqueComplex); // 每个元素都是唯一的

这种方法通过JSON.stringify将对象转为字符串进行比较,但要注意对象属性顺序必须一致。

7. 排序后去重(适用于可排序数据)

javascript

ini 复制代码
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr
  .sort((a, b) => a - b)
  .filter((item, index, array) =>
    index === 0 || item !== array[index - 1]
  );
console.log(uniqueArr); // [1, 2, 3, 4, 5]

先排序,然后过滤掉与前一元素相同的元素。注意这会改变原数组的顺序。

性能对比与使用建议

方法 适用场景
Set 简单数据类型,现代浏览器
filter+indexOf 兼容性要求高
reduce 需要自定义逻辑
Map对象 对象数组去重

日常开发建议

  • 简单数组去重:优先使用 [...new Set(arr)]
  • 对象数组去重:使用 Map 方法
  • 兼容性要求:使用 filter + indexOf
  • 复杂数据:使用 reduce + JSON.stringify
相关推荐
kyriewen2 小时前
我review了一份Vibe Coding写的前端代码——能跑,但5个地方迟早要命
前端·javascript·ai编程
Hilaku4 小时前
为什么在 2026 年,MPA(多页面应用)正在悄悄复辟?
前端·javascript·程序员
悟空瞎说5 小时前
iOS 高效绘图
javascript
触底反弹5 小时前
🔥 从 MySQL 到 Milvus:用 AI 日记本项目搞懂向量数据库和 RAG
javascript·人工智能·面试
妙码生花5 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(三十九):前端上传组件实现
javascript·vue.js·ai编程
dota李天王5 小时前
简单的 socket 实现
前端·javascript·websocket
寒水馨7 小时前
Linux下载、安装 Bun v1.3.14(附安装包bun-linux-x64.zip)
linux·javascript·typescript·node.js·bun·运行时·包管理器
windliang7 小时前
Claude Code 源码分析(一):从 claude 命令到 Agent 主循环
javascript·面试·ai编程
申君健24864182772027 小时前
WebGPU 内部运行原理:Format、Texture 与 GPU 侧到底在干什么
javascript
JoyT7 小时前
Nuxt 3的核心设计与静态官网应用
前端·javascript·vue.js