【js数组去重的方法】在JavaScript开发中,数组去重是一个非常常见的需求。当处理数据时,我们常常需要去除重复的元素以提高效率或避免错误。以下是几种常用的JS数组去重方法,适用于不同的场景和数据类型。
一、常用去重方法总结
方法名称 | 实现方式 | 是否支持对象去重 | 是否保留顺序 | 是否兼容旧浏览器 | 适用场景 |
`Set` + `Array.from()` | `Array.from(new Set(arr))` | ❌ | ✅ | ✅ | 简单、高效、现代浏览器 |
`filter` + `indexOf` | `arr.filter((v, i) => arr.indexOf(v) === i)` | ❌ | ✅ | ✅ | 简单易懂,适合基础使用 |
`reduce` | `arr.reduce((acc, v) => acc.includes(v) ? acc : [...acc, v], [])` | ❌ | ✅ | ✅ | 可自定义逻辑,灵活性高 |
`filter` + `includes` | `arr.filter((v, i) => arr.slice(0, i).includes(v) === false)` | ❌ | ✅ | ✅ | 保留顺序,逻辑清晰 |
`for循环` | 通过遍历数组并手动判断是否重复 | ✅(需自定义) | ✅ | ✅ | 适用于复杂对象或特殊逻辑 |
`Map` 或 `Object` | 利用键值对去重 | ✅(需自定义) | ❌ | ✅ | 适合处理对象或复杂数据类型 |
二、具体实现示例
1. 使用 `Set` 去重
```javascript
const arr = [1, 2, 3, 2, 4];
const uniqueArr = Array.from(new Set(arr)); // [1, 2, 3, 4
```
- 优点:简洁高效,代码量少。
- 缺点:不支持对象去重,且不保留原始顺序(虽然实际测试中顺序是保留的)。
2. 使用 `filter` + `indexOf`
```javascript
const arr = [1, 2, 3, 2, 4];
const uniqueArr = arr.filter((v, i) => arr.indexOf(v) === i);
// [1, 2, 3, 4
```
- 优点:简单直观。
- 缺点:性能较差,因为每次都要查找整个数组。
3. 使用 `reduce` 去重
```javascript
const arr = [1, 2, 3, 2, 4];
const uniqueArr = arr.reduce((acc, v) => {
return acc.includes(v) ? acc : [...acc, v];
}, []);
// [1, 2, 3, 4
```
- 优点:逻辑灵活,可扩展性强。
- 缺点:代码略显复杂。
4. 使用 `filter` + `slice` + `includes`
```javascript
const arr = [1, 2, 3, 2, 4];
const uniqueArr = arr.filter((v, i) => !arr.slice(0, i).includes(v));
// [1, 2, 3, 4
```
- 优点:保留顺序,逻辑清晰。
- 缺点:性能不如 `Set`。
5. 使用 `for` 循环手动去重
```javascript
function unique(arr) {
const result = [];
for (let i = 0; i < arr.length; i++) {
if (!result.includes(arr[i])) {
result.push(arr[i]);
}
}
return result;
}
```
- 优点:可自定义逻辑,适用于对象等复杂数据。
- 缺点:代码量多,不够优雅。
6. 使用 `Map` 或 `Object` 去重(支持对象)
```javascript
function uniqueWithObject(arr) {
const seen = {};
const result = [];
for (let i = 0; i < arr.length; i++) {
const key = JSON.stringify(arr[i]);
if (!seen[key]) {
seen[key] = true;
result.push(arr[i]);
}
}
return result;
}
```
- 优点:支持对象去重。
- 缺点:需要将对象转为字符串,可能影响性能。
三、总结
在实际开发中,根据数据类型和项目需求选择合适的去重方式非常重要。对于基本类型的数据,推荐使用 `Set` 或 `filter`;对于对象等复杂类型,则需要结合 `Map` 或 `Object` 进行处理。此外,保持代码简洁、可读性高也是值得重视的开发习惯。