JS数组去重的5种算法实现与兼容性处理

作者:纸飞机

时间:2026-10-29

浏览:167

本文详细解析JavaScript中数组去重的五种常见实现方式,包括遍历法、对象键值对法、下标判断法、排序相邻法及优化遍历法。重点对比各方法的执行速度与内存占用,并针对IE8及以下浏览器不支持ECMAScript 5 indexOf方法的问题,提供兼容代码实现,帮助开发者根据场景选择最优方案。

文章目录

JS数组去重的5种算法实现与兼容性处理

第一种方法是遍历数组法,这是最基础的去重思路。具体实现为创建一个新数组,遍历原始数组中的每个元素,如果该元素不在新数组中,则将其添加进去。需要注意的是,判断元素是否存在主要依赖“indexOf”方法,这是ECMAScript 5标准引入的特性。在IE8及更早版本的浏览器中,该方法不被支持,因此若需兼容低版本浏览器,必须额外编写兼容代码。


// 最简单数组去重法 
function unique1(array){ 
var n = []; //一个新的临时数组 
//遍历当前数组 
for(var i = 0; i < array.length; i++){ 
//如果当前数组的第i已经保存进了临时数组,那么跳过, 
//否则把当前项push到临时数组里面 
if (n.indexOf(array[i]) == -1) n.push(array[i]); 
} 
return n; 
} 

第二种方法是对象键值对法,其执行速度在所有方法中通常最快,但代价是占用较多的内存空间,属于以空间换时间的策略。实现逻辑是构建一个JS对象和一个新数组,遍历原数组时,检查当前值是否已作为对象的键存在。若不存在,则将该值设为对象的键并加入新数组。此方法的一个潜在问题是,对象键会自动调用“toString()”进行转换,导致数字1和字符串“1”可能被误判为相同键。若要解决此类类型混淆问题,仍需结合“indexOf”进行额外判断。


// 速度最快, 占空间最多(空间换时间) 
function unique2(array){ 
var n = {}, r = [], len = array.length, val, type; 
for (var i = 0; i < array.length; i++) { 
val = array[i]; 
type = typeof val; 
if (!n[val]) { 
n[val] = [type]; 
r.push(val); 
} else if (n[val].indexOf(type) < 0) { 
n[val].push(type); 
r.push(val); 
} 
} 
return r; 
} 

第三种方法是数组下标判断法,其性能表现与方法1相近,同样依赖“indexOf”。实现思路是:遍历数组时,检查当前第i项在当前数组中首次出现的位置索引是否等于i。如果首次出现的位置不是i,说明该项是重复元素,直接忽略;否则,将其存入结果数组。


function unique3(array){ 
var n = [array[0]]; //结果数组 
//从第二项开始遍历 
for(var i = 1; i < array.length; i++) { 
//如果当前数组的第i项在当前数组中第一次出现的位置不是i, 
//那么表示第i项是重复的,忽略掉。否则存入结果数组 
if (array.indexOf(array[i]) == i) n.push(array[i]); 
} 
return n; 
} 

第四种方法是排序后相邻去除法。尽管原生数组的“sort”方法默认排序结果可能不符合数值大小预期,但在不严格要求顺序的去重场景中,这一缺点可以忽略。实现步骤为:首先对传入数组进行排序,使相同值相邻,然后遍历排序后的数组,仅将与前一个值不同的元素加入新数组。


// 将相同的值相邻,然后遍历去除重复值 
function unique4(array){ 
array.sort(); 
var re=[array[0]]; 
for(var i = 1; i < array.length; i++){ 
if( array[i] !== re[re.length-1]){ 
  re.push(array[i]); 
 } 
 } 
 return re; 
} 

第五种方法是优化遍历数组法,其代码实现较为精简高效。核心思路是获取每个元素最后一次出现的位置,并将其放入新数组。具体逻辑为:当检测到当前元素与后续元素重复时,终止当前内层循环并进入外层循环的下一轮判断,从而只保留最右侧的那个唯一值。此方法被推荐为较优方案。


// 思路:获取没重复的最右一值放入新数组 
function unique5(array){ 
var r = []; 
for(var i = 0, l = array.length; i < l; i++) { 
 for(var j = i + 1; j < l; j++) 
  if (array[i] === array[j]) j = ++i; 
 r.push(array[i]); 
 } 
 return r; 
} 

针对IE8及以下浏览器(仅支持部分ECMAScript 5标准)不支持“indexOf”方法的情况,需要手动扩展Array原型以提供兼容支持。


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; 
} 
} 

综上所述,以上五种JS数组去重的算法实现各有优劣,开发者可根据具体性能需求和环境兼容性要求选择合适的方法,希望这些内容能对学习有所帮助。

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章