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
相关推荐
Liu.77419 小时前
vue3使用vue3-print-nb打印
前端·javascript·vue.js
dly_blog20 小时前
Vue 逻辑复用的多种方案对比!
前端·javascript·vue.js
wyzqhhhh21 小时前
京东啊啊啊啊啊
开发语言·前端·javascript
想学后端的前端工程师21 小时前
【Java集合框架深度解析:从入门到精通-后端技术栈】
前端·javascript·vue.js
GISer_Jing21 小时前
Nano Banana:AI图像生成与编辑新标杆
前端·javascript·人工智能
csdn_aspnet1 天前
用100行實現HTML5可存檔塗鴉版
javascript
布茹 ei ai1 天前
城市天气查询系统 (City Weather Dashboard)
javascript·vue.js·html·css3·开源软件·天气预报
梵尔纳多1 天前
Electron 主进程和渲染进程通信
javascript·arcgis·electron
巴拉巴拉~~1 天前
Flutter 通用滑块组件 CommonSliderWidget:单值 / 范围 + 刻度 + 标签 + 样式自定义
开发语言·前端·javascript
有意义1 天前
从 useState 到 useEffect:React Hooks 核心机制详解
javascript·react.js·前端工程化