JavaScript数组去重算法实现与对比分析
本文总结了JavaScript中几种常见的数组去重算法,包括基于双循环匹配、利用对象Key唯一性的JSON/对象去重、队列排序递归以及indexOf方法。文章详细分析了各方法的代码实现、优缺点及潜在Bug,如类型区分问题和浏览器兼容性问题,旨在为面试复习和实际开发提供参考。
前言与概述
前言
近期为应对求职面试,开始系统复习JavaScript相关知识。昨日在思考数组去重相关问题时,决定整理一系列JavaScript算法文章以备后用。本系列文章篇幅和发布时间不固定,随想随写,内容侧重个人理解,不保证绝对正确或高效,若有疏漏欢迎指正。
关于去重
数组去重是常见的算法考点,其核心逻辑主要基于数据的唯一性或非唯一性特征,即筛选出唯一元素或剔除重复元素。以下介绍的算法均为作者自行命名,仅供参考。
循环匹配去重法
循环匹配去重
该方法直观地将数组中每个元素与存放结果的新数组进行逐一比对,若发现不重复的元素则加入新数组,直至遍历结束。由于涉及外层遍历与内层匹配的双重循环,也可称为双循环匹配去重,这是最基础且易于理解的方式。
实现代码:
var arr=[1,3,4,56,3,7,9,7];
var result=[];
//匹配
function isMatch(array,n){
for(var i=0;i<array.length;i++){
if(array[i]==n){
return true;
}
}
return false;
};
//验证所有元素
function unqiue(array){
for(var i=0;i<array.length;i++){
if(!isMatch(result,array[i])){
result.push(array[i]);
}
}
return result;
};
console.log(unqiue(arr));
注意:上述方法存在一个缺陷,当数组中同时包含数字和数字形式的字符串时,无法准确区分二者。原因在于匹配函数isMatch()中使用了双等号“==”,未严格校验元素类型,实际开发中应使用全等“===”进行严格比较。修改后的代码如下:
var arr=[1,3,4,56,3,'1',7,9,7];
var result=[];
//匹配
function isMatch(array,n){
for(var i=0;i<array.length;i++){
if(array[i]===n){
return true;
}
}
return false;
};
//验证所有元素
function unqiue(array){
for(var i=0;i<array.length;i++){
if(!isMatch(result,array[i])){
result.push(array[i]);
}
}
return result;
};
console.log(unqiue(arr));
算法优缺点:
优点:
实现简单,思路直观
缺点:
效率低下
JSON与对象键值去重法
JSON去重/对象去重/字典去重
JSON去重的核心在于利用Object对象Key的唯一性。具体做法是将数组元素转换为JSON对象或普通对象的Key值,Value存储原数组的索引index,随后通过for...in循环遍历该JSON对象,将Key值存储到新数组中。
由于Array、JSON以及{}在JavaScript中均属于Object类型,因此采用任意一种方式均可实现此算法。
实现代码:
Array方式:
var arr=[1,3,4,56,3,'1',7,9,7];
function unqiue(array){
var cache=[];
var result=[];
//将数组元素转为对象的key
for(var i=0;i<array.length;i++){
cache[array[i]]=i;
};
//存储key(实际的数组元素)
for(key in cache){
result.push(key);
};
return result;
}
console.log(unqiue(arr));
JSON方式:
var arr=[1,3,4,56,3,'1',7,9,7];
function unqiue(array){
var cache={};
var result=[];
//将数组元素转为对象的key
for(var i=0;i<array.length;i++){
cache[array[i]]=i;
};
//存储key(实际的数组元素)
for(key in cache){
result.push(key);
};
return result;
}
console.log(unqiue(arr));
Object方式:
var arr=[1,3,4,56,3,'1',7,9,7];
function unqiue(array){
var cache=new Object();
var result=[];
//将数组元素转为对象的key
for(var i=0;i<array.length;i++){
cache[array[i]]=i;
};
//存储key(实际的数组元素)
for(key in cache){
result.push(key);
};
return result;
}
console.log(unqiue(arr));
算法优缺点:
优点:
简单
效率非常高
缺点:
1.改变了数组元素的类型() 2.有bug(无非区分数字和数字类型字符串)
队列递归去重法
队列递归去重
经过深入思考,提出使用队列方式进行处理。首先将数组排序为升序或降序队列,使相同元素聚集在同一区域。随后从队尾向前进行匹配,若匹配成功则删除队尾元素,接着前一个元素继续向前匹配。整个匹配过程完成后,剩余元素即为去重后的结果。
var arr=[6, 4, 6, 9, '6', 13, 56, 9, ,'11',1, 8, '7', 17, 5, 45, 3, 7];
function unqiue(array){
//排序数组,形成队列
array.sort(function(m,n){return m-n;});
////排序后,队尾向前对比,如果相同,删除队尾,依次类推
function loop(Index){
if(Index>=1){
if(array[Index]===array[Index-1]){
arr.splice(Index,1);
}
loop(Index-1);
}
}
loop(array.length-1);
return array;
}
console.log(unqiue(arr));
算法优缺点:
优点:
效率较高
缺点:
效率不是最高
indexOf方法去重与兼容处理
INDEXOF去重方式
判断浏览器是否支持indexOf ,indexOf 为ecmaScript5新方法 IE8以下(包括IE8, IE8只支持部分ecma5)不支持
if (!Array.prototype.indexOf){
// 新增indexOf方法
Array.prototype.indexOf = function(item){
var result = -1, a_item = null;
if (this.length == 0){
return result;
}
for(var i = 0, len = this.length; i < len; i++){
a_item = this[i];
if (a_item === item){
result = i;
break;
}
}
return result;
}
}
ES6模块化中js文件怎么用import和export交互
2026-11-05 17:00:48
JS读取本地文件时报错或无响应的常见原因
2026-11-05 16:32:31
let、const与var的区别:JavaScript变量声明最佳实践
2026-11-05 14:16:38
JS中直接定义静态二维数组的字面量写法
2026-11-05 14:16:08
JS 怎么查找字符串中所有匹配项的位置
2026-11-05 14:15:53
