JavaScript 数组去重方法汇总:从 Set 到 reduce 7种方案

小飞兽 JavaScript 338 次阅读 2026-05-15

Introduction

数组去重是 JavaScript 开发中的常见需求,本文汇总 7 种去重方法,从 ES6 Set(最简洁)到 reduce(最灵活),覆盖不同场景的优缺点和性能对比。

方法1:Set(ES6,推荐)

/* Set 是一种不允许重复值的数据结构 */
var arr = [1, 2, 2, 3, 3, 3, 'a', 'a'];
var unique = [...new Set(arr)];
// [1, 2, 3, 'a']

/* 或使用 Array.from */
var unique2 = Array.from(new Set(arr));

/* 优点:语法简洁,性能好 */
/* 缺点:无法去除 {}、[] 等引用类型重复(因为引用不相等)*/

方法2:filter + indexOf

var unique = arr.filter(function(item, index) {
    return arr.indexOf(item) === index;
});
/* 保留第一次出现的位置,后续重复项被过滤 */

方法3:reduce + includes

var unique = arr.reduce(function(acc, item) {
    if (!acc.includes(item)) {
        acc.push(item);
    }
    return acc;
}, []);
console.log(unique);

方法4:对象键值对(处理引用类型)

/* 只能处理原始值(数字、字符串)*/
var unique = Object.keys(
    arr.reduce(function(obj, item) {
        obj[item] = true;
        return obj;
    }, {})
); // 返回字符串键,需要 Number() 转换

/* 改进版:处理数字和字符串混合 */
var unique = arr.filter(function(item) {
return typeof item + '|' + item;
}).filter(function(item, index, self) {
return self.indexOf(item) === index;
});

方法5:排序后相邻比较

var sorted = arr.slice().sort(function(a, b) { return a - b; });
var unique = sorted.filter(function(item, index) {
    return item !== sorted[index - 1];
});
/* 注意:sort 是字符串排序,需要自定义比较函数处理数字 */

性能对比

/* 10万条数据下测试结果(从快到慢):*/
/* 1. Set:最快,O(n) 复杂度 */
/* 2. Object 键值对:O(n) */
/* 3. filter + indexOf:O(n^2),但代码最简洁 */
/* 4. reduce + includes:O(n^2) */

常见问题

    • NaN 去重:Set 能正确处理 NaN(NaN === NaN 为 false),但 indexOf 方法不能(因为 NaN !== NaN)。
  • 引用类型去重:Set 无法去除 {a:1} 和 {a:1},因为引用地址不同。需要手动用 JSON.stringify 或哈希函数处理。
  • 大量数据:对于百万级数据,Set 是唯一合理选择。

延伸阅读