JavaScript数组去重方法终极总结

作者:闭包旅人时间:2026-10-28 11:52:23浏览:502

本文总结了多种JavaScript数组去重方法,包括双重循环、排序结合indexOf以及哈希表方案。文章详细分析了各方法在IE6-8等旧版浏览器中的兼容性问题与性能差异,并指出了字符串与数字混合时的潜在Bug及修正方案,帮助开发者根据实际场景选择最优解。

JavaScript数组去重方法终极总结

有时会遇到这样的需求:删除数组中重复的元素,仅保留唯一值。最直接的想法可能是使用两个for循环进行比较,然后剔除重复项,具体代码实现如下:

方法1:

代码如下:

Array.prototype.distinct = function(){
var arr = [],
len = this.length;
for ( var i = 0; i < len; i++ ){
 for( var j = i+1; j < len; j++ ){
 if( this[i] === this[j] ){
 j = ++i;
 }
 }
 arr.push( this[i] );
 }
 return arr;
};

使用方法1在数据量较大时,性能表现会显著下降。接下来请看下面的其他方法。

方法2:

代码如下:

Array.prototype.distinct = function(){
var self = this,
arr = self.concat().sort(); // 创建一个新数组并排序
arr.sort(function( a, b ){
 if( a === b ){
 var n = self.indexOf( a ); //获取索引值
 self.splice( n, 1 );
 return self;
 }
});
if( a === b ){
 var n = self.indexOf( a ); //获取索引值
 self.splice( n, 1 );
 return self;
var n = self.indexOf( a ); //获取索引值
self.splice( n, 1 );
  }
 });
return self;
};

方法2使用了 sort 的自定义回调函数,同时也用到了 indexOf 这个IE6/7/8不支持的方法。当然,indexOf可以自己模拟,但是更大的问题是IE6/7/8的sort方法和标准浏览器之间也有差别。在IE6/7/8中使用 sort 方法的自定义回调函数陷阱比较多,上面的自定义 sort 的回调函数的代码在IE6/7/8中会直接报“缺少数字”的错误,回调函数的返回是NaN的话就会报这个错,因为理论上 sort 的回调函数只能返回整数。就算忽略返回值的问题还是有其他问题,最后也没有过多的去纠结了,方法2在IE6/7/8中行不通。

从愚人码头那里看来了方法3,下面是他的代码:

代码如下:

Array.prototype.delRepeat=function(){
var newArray=[];
var provisionalTable = {};
for (var i = 0, item; (item= this[i]) != null; i++) {
 if (!provisionalTable[item]) {
 newArray.push(item);
 provisionalTable[item] = true;
 }
}
if (!provisionalTable[item]) {
 newArray.push(item);
 provisionalTable[item] = true;
newArray.push(item);
provisionalTable[item] = true;
        }
    }
return newArray;
};

方法3使用了一个临时的对象来存储数组的元素,如果碰上重复的数组元素,将会忽略掉。但是,如果碰到下面这种数组:

代码如下:

var arr = [ 'firefox', 1, '1' ];

上面的数组如果用方法3会误将 1 和 “1” 当成重复元素而删除掉,于是有将方法3做了一点点的小修改,可以解决这个BUG。 方法3的修改版:

代码如下:

Array.prototype.distinct = function(){
var arr = [],
obj = {},
i = 0,
len = this.length,
result;
for( ; i < len; i++ ){
 result = this[i];
 if( obj[result] !== result ){
 arr.push( result );
 obj[result] = result;
 }
}
return arr;
};

之后又看了愚人码头文章后面的评论,该方法和Rekey提供的方法是一样的,但是这个方法也有BUG,如果碰到这样的2B数组就杯具了:

代码如下:

var arr = [ 'firefox', 1, '1', 1 ];

上面的数组用方法3的修改版,将不会删除后3个元素,不过这种数组有点极端了,如果碰到字符串字面量和数字相同的数据应该预先处理下以规避这种BUG。使用临时对象的方法比 sort 在标准浏览器中略快,sort 方法在各浏览器中的算法应该也有区别。

作者最新文章

相关标签: