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
相关推荐
汤姆Tom39 分钟前
前端转战后端:JavaScript 与 Java 对照学习指南 (第一篇 - 深度进阶版)
java·javascript
Cassie燁41 分钟前
element-plus源码解读2——vue3组件的ref访问与defineExpose暴露机制
javascript·vue.js
Robet43 分钟前
类属性公共还是私有
javascript·typescript
x***B4111 小时前
TypeScript项目引用
前端·javascript·typescript
●VON1 小时前
使用 Electron 构建天气桌面小工具:调用公开 API 实现跨平台实时天气查询V1.0.0
前端·javascript·electron·openharmony
穷人小水滴2 小时前
使用 epub 在手机快乐阅读
javascript·deno·科幻
爱学习的程序媛4 小时前
《深入浅出Node.js》核心知识点梳理
javascript·node.js
Robet5 小时前
TS和JS成员变量修饰符
javascript·typescript
方法重载5 小时前
前端性能优化之“代码分割与懒加载”)
javascript