JavaScript数字数组去重的四种方法及性能对比

阿麦
阿麦
发布时间:2026-10-15| 5人浏览过
原创

本文深入探讨了在 JavaScript 中去除数组重复项的多种实现方式,重点分析了基于双层循环、排序替换、对象属性映射以及排序相邻比较这四种核心算法,并通过具体的性能测试脚本对比了它们的执行效率。

结果与目标

在数据处理过程中,经常需要去除数组中的重复元素。不同的实现思路在代码复杂度和运行性能上存在显著差异。本文将展示如何通过 Array.prototype 扩展原生方法来实现去重,并直观呈现它们在处理包含大量随机数据的数组时的耗时表现。

准备条件

所有示例均基于浏览器环境运行。为了准确评估不同方法的性能,我们需要一个模拟的大规模随机数据源,以及一个能够记录代码执行时间的监控工具。以下是用于生成测试数据和统计耗时的基础结构。

第1步:构建测试数据源

为了观察去重效果及性能,我们首先生成一个包含2000个随机数字(范围1-2000)的字符串数组。这段代码通过闭包维持状态,确保每次调用 test() 都能返回一份新鲜的数据副本,以保证测试的准确性。

var test=(function() {
    var arr2=[];
    for(var i=0; i<2000; i++) {
        var t=i;
        t=parseInt(Math.random()*2000)+1;
        arr2[i]=(t.toString());
    }
    return function(){
        return arr2;
    };
})();

第2步:集成性能监控工具

使用自定义的 Watch 对象来标记代码段的开始与结束,自动计算耗时并生成可视化报告。该工具会在页面底部以条形图形式展示各方法的耗时占比,便于直观对比。

var Watch = {
    result: [],
    guid: -1,
    totalTime: 0,
    start: function(title){
        this.result[++this.guid] = [title || this.guid, new Date().getTime()];
    },
    stop: function(){
        var r = this.result[this.guid];
        var t = new Date().getTime() - r[1];
        this.totalTime += t;
        r[1] = t;
    },
    report: function(parent){
        // ... 省略部分DOM操作代码 ...
        parent.appendChild(div);
        div = null;
        this.totalTime = 0;
        this.guid = -1;
        this.result=[];
    }
};
// 简易控制台兼容处理
if(!console){
    var console={};
    console.log=function(str){alert(str);}
}

真实操作顺序

以下是四种核心的去重算法实现及其逻辑解析。

第3步:使用双层循环遍历去重 (unique1)

目的: 最直观的去重逻辑,适合理解基础算法原理。 入口: 数组原型。
动作: 创建新数组 r。外层循环遍历原数组,内层循环检查新数组中是否已存在当前元素。若不存在,则加入新数组;若存在,则跳过(continue label)。

Array.prototype.unique1 = function () {
    var r = new Array();
    label:for(var i = 0, n = this.length; i < n; i++) {
        for(var x = 0, y = r.length; x < y; x++) {
            if(r[x] == this[i]) {
                continue label;
            }
        }
        r[r.length] = this[i];
    }
    return r;
}

第4步:利用排序与正则表达式去重 (unique2)

目的: 利用字符串处理能力简化代码,但需注意类型转换风险。 入口: 数组原型。
动作: 先将数组排序,转为字符串后,使用复杂的正则表达式匹配重复出现的子串并将其替换。最后再拆分回数组。这种方法在处理纯数字字符串时有效,但对对象或特殊格式可能失效。

Array.prototype.unique2 = function () {
    return this.sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(",");
}

第5步:利用对象属性唯一性去重 (unique3)

目的: 在数据量较大时提供较优的性能表现。 入口: 数组原型。
动作: 创建一个临时对象 temp。遍历原数组,将每个元素作为对象的键值存入。由于对象键名不可重复,重复的元素会被后面的覆盖或忽略。最后遍历对象获取所有键名组成新数组。注释中提到此法在数组很大时最快。

Array.prototype.unique3 = function() {
    var temp = {}, len = this.length;
    for(var i=0; i < len; i++) {
        var tmp = this[i];
        if(!temp.hasOwnProperty(tmp)) {
            temp[this[i]] = "my god";
        }
    }
    len = 0;
    var tempArr=[];
    for(var i in temp) {
        tempArr[len++] = i;
    }
    return tempArr;
}

第6步:排序后相邻比较去重 (unique4)

目的: 避免内层循环,通过排序使重复项相邻从而线性扫描。 入口: 数组原型。
动作: 先对原数组进行排序。随后遍历数组,如果当前元素与下一个元素相同,则跳过;否则将其加入结果数组。注意此方法会改变原数组的顺序。

Array.prototype.unique4 = function () {
    var temp = new Array();
    this.sort();
    for(i = 0; i < this.length; i++) {
        if( this[i] == this[i+1]) {
            continue;
        }
        temp[temp.length]=this[i];
    }
    return temp;
}

完成判断与性能测试

在页面加载完成后,依次调用上述四种方法,并通过 Watch 工具输出耗时对比。测试结果显示了每种方法处理2000条数据的实际执行时间,其中 unique3 通常在大数据量下表现最佳。

简要总结

以上关于 JavaScript 数字数组去重四种实现方式及性能测试的详细内容,更多关于 JavaScript 数组优化的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。