javascript数组去重方法终极总结

 更新时间:2014年06月05日 11:22:34   作者:  
这篇文章主要介绍了javascript数组去重终极总结,本文列举了3种javascript数组去重方法,并分别分析了它们的优缺点,需要的朋友可以参考下

有时会碰上这种需求,需要将数组中重复的元素删除掉,而只保留一个。最先想到的办法很可能就是用2个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;

};

方法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;
        }
    }
    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 方法在各浏览器中的算法应该也有区别。

相关文章

  • es6学习笔记之Async函数的使用示例

    es6学习笔记之Async函数的使用示例

    async 函数,使得异步操作变得更加方便。它是 Generator 函数的语法糖。下面这篇文章主要给大家介绍了es6学习笔记之Async函数使用的相关资料,文中给出了详细的示例代码,需要的朋友们下面来一起看看吧。
    2017-05-05
  • JS中注入eval, Function等系统函数截获动态代码

    JS中注入eval, Function等系统函数截获动态代码

    这篇文章主要介绍了JS中注入eval, Function等系统函数截获动态代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • 基于Javascript实现文件实时加载进度的方法

    基于Javascript实现文件实时加载进度的方法

    不知道大家有没有发现在现在的移动页面上,有很多情况需要加载大量的资源。但是移动端的访问速度和pc还是有很大的差距,有些时候需要一些取巧的方式来提升用户体验,而实时显示加载进度就是其中一种。这篇文章就给大家分享了Javascript实现文件实时加载进度的方法。
    2016-10-10
  • js图片无缝滚动插件使用详解

    js图片无缝滚动插件使用详解

    这篇文章主要为大家详细介绍了js图片无缝滚动插件的使用方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • js判断为空Null与字符串为空简写方法

    js判断为空Null与字符串为空简写方法

    最近开始研究JavaScript的简写方法,下面就是有关判断为空的简写方法
    2014-02-02
  • 小程序双头slider选择器的实现示例

    小程序双头slider选择器的实现示例

    这篇文章主要介绍了小程序双头slider选择器的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • uniapp退出关闭当前小程序或APP的简单实现

    uniapp退出关闭当前小程序或APP的简单实现

    最近通过Uniapp开发APP又一个非常实用的功能,这篇文章主要给大家介绍了关于uniapp退出关闭当前小程序或APP的简单实现,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • WebGL利用FBO完成立方体贴图效果完整实例(附demo源码下载)

    WebGL利用FBO完成立方体贴图效果完整实例(附demo源码下载)

    这篇文章主要介绍了WebGL利用FBO完成立方体贴图效果的方法,以完整实例形式分析了WebGL实现立方体贴图的具体步骤与相关技巧,并附带了demo源码供读者下载参考,需要的朋友可以参考下
    2016-01-01
  • 原生js的数组除重复简单实例

    原生js的数组除重复简单实例

    下面小编就为大家带来一篇原生js的数组除重复简单实例。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • JavaScript实现三级级联特效

    JavaScript实现三级级联特效

    这篇文章主要介绍了JavaScript实现三级级联特效,选择省会出现相应的县下拉框,同时市的下拉框改变,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11

最新评论