导读

在JavaScript中,数组去重有多种实现方式。本文将对10种常见的去重方法进行性能分析,并按执行时间从快到慢排序。


性能排序

以下是10种去重方法的性能排序(从最快到最慢):

  1. 使用 Set
  2. 使用 Array.fromSet
  3. 使用 reduceSet 结合
  4. 使用 ObjectMap
  5. 使用 reduceObject 结合
  6. 使用 filterindexOf
  7. 使用 forEachincludes
  8. 使用 reduce
  9. 使用 for 循环
  10. 使用 lodash

性能分析

1. 使用 Set

Set 是专门用于存储唯一值的数据结构,其去重操作的时间复杂度为 O(n),是所有方法中最快的。

1
const uniqueArray = [...new Set(array)];

2. 使用 Array.fromSet

与直接使用 Set 类似,Array.fromSet 转换为数组,性能接近 Set

1
const uniqueArray = Array.from(new Set(array));

3. 使用 reduceSet 结合

通过 reduceSet 结合,性能略低于直接使用 Set,但仍非常高效。

1
const uniqueArray = Array.from(array.reduce((acc, item) => acc.add(item), new Set()));

4. 使用 ObjectMap

利用对象的键或 Map 的唯一性,时间复杂度为 O(n),但由于对象操作的开销,性能略低于 Set

1
const uniqueArray = Object.keys(array.reduce((acc, item) => (acc[item] = true, acc), {}));

5. 使用 reduceObject 结合

与上一种方法类似,但使用 Object.values 提取值,性能稍低。

1
const uniqueArray = Object.values(array.reduce((acc, item) => (acc[item] = item, acc), {}));

6. 使用 filterindexOf

indexOf 的时间复杂度为 O(n),因此整体时间复杂度为 O(n^2),性能较差。

1
const uniqueArray = array.filter((item, index) => array.indexOf(item) === index);

7. 使用 forEachincludes

includes 的时间复杂度为 O(n),因此整体时间复杂度为 O(n^2),性能与 filterindexOf 接近。

1
2
const uniqueArray = [];
array.forEach(item => { if (!uniqueArray.includes(item)) uniqueArray.push(item); });

8. 使用 reduce

通过 reduceincludes 结合,时间复杂度为 O(n^2),性能较差。

1
const uniqueArray = array.reduce((acc, item) => (!acc.includes(item) && acc.push(item), acc), []);

9. 使用 for 循环

传统的 for 循环结合 includes,时间复杂度为 O(n^2),性能较差。

1
2
3
4
const uniqueArray = [];
for (let i = 0; i < array.length; i++) {
if (!uniqueArray.includes(array[i])) uniqueArray.push(array[i]);
}

10. 使用 lodash

lodash_.uniq 方法虽然方便,但由于是第三方库,性能通常不如原生方法。

1
const uniqueArray = _.uniq(array);

总结

方法 时间复杂度 性能排名
使用Set O(n) 1
使用Array.fromSet O(n) 2
使用reduceSet 结合 O(n) 3
使用ObjectMap O(n) 4
使用reduceObject 结合 O(n) 5
使用filterindexOf O(n^2) 6
使用forEachincludes O(n^2) 7
使用reduce O(n^2) 8
使用for 循环 O(n^2) 9
使用lodash O(n) 10