JavaScript数组去重算法实现与对比分析

作者:青柠

时间:2026-10-29

浏览:653

本文总结了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; 
} 
} 

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章