前言
在前端开发中,数组去重是一个常见的需求。无论是处理用户数据、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