javascript数组去重方法终极总结


Posted in Javascript onJune 05, 2014

有时会碰上这种需求,需要将数组中重复的元素删除掉,而只保留一个。最先想到的办法很可能就是用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 方法在各浏览器中的算法应该也有区别。

Javascript 相关文章推荐
JavaScript 基础问答三
Dec 03 Javascript
怎么清空javascript数组
May 11 Javascript
js 跳出页面的frameset框架示例介绍
Dec 23 Javascript
javascript显示倒计时控制按钮的简单实现
Jun 07 Javascript
js实现的页面加载完毕之前loading提示效果完整示例【附demo源码下载】
Aug 02 Javascript
jQuery实现拖拽可编辑模块功能代码
Jan 12 Javascript
详解Vue2.0之去掉组件click事件的native修饰
Apr 20 Javascript
利用canvas实现的加载动画效果实例代码
Jul 05 Javascript
深入讲解xhr(XMLHttpRequest)/jsonp请求之abort
Jul 26 Javascript
微信小程序实现拖拽 image 触摸事件监听的实例
Aug 17 Javascript
详解Nuxt.js部署及踩过的坑
Aug 07 Javascript
Nuxt.js实战和配置详解
Aug 05 Javascript
javascript设计模式之解释器模式详解
Jun 05 #Javascript
javascript监听鼠标滚轮事件浅析
Jun 05 #Javascript
详解JavaScript语法对{}处理的坑爹之处
Jun 05 #Javascript
封装了一个支持匿名函数的Javascript事件监听器
Jun 05 #Javascript
用js读、写、删除Cookie代码分享及详细注释说明
Jun 05 #Javascript
NODE.JS加密模块CRYPTO常用方法介绍
Jun 05 #Javascript
jquery左边浮动到一定位置时显示返回顶部按钮
Jun 05 #Javascript
You might like
IIS下配置Php+Mysql+zend的图文教程
2006/12/08 PHP
php getimagesize 上传图片的长度和宽度检测代码
2010/05/15 PHP
ThinkPHP查询返回简单字段数组的方法
2014/08/25 PHP
php数组键名技巧小结
2015/02/17 PHP
Laravel 5框架学习之路由、控制器和视图简介
2015/04/07 PHP
PHP微信分享开发详解
2017/01/14 PHP
thinkPHP框架动态配置用法实例分析
2018/06/14 PHP
js 表单提交后按钮变灰的实例代码
2013/08/16 Javascript
jQuery 重复加载错误以及修复方法
2014/12/16 Javascript
使用jQuery制作Web页面遮罩层插件的实例教程
2016/05/26 Javascript
jQuery文字轮播特效
2017/02/12 Javascript
nodejs密码加密中生成随机数的实例代码
2017/07/17 NodeJs
使用vue制作FullPage页面滚动效果
2017/08/21 Javascript
Angular使用cli生成自定义文件、组件的方法
2018/09/04 Javascript
详解vue-cli 脚手架 安装
2019/04/16 Javascript
vue router导航守卫(router.beforeEach())的使用详解
2019/04/19 Javascript
生产制造追溯系统之再说条码打印
2019/06/03 Javascript
解决vue单页面应用中动态修改title问题
2019/06/09 Javascript
vue中利用three.js实现全景图的完整示例
2020/12/07 Vue.js
Vue3 实现双盒子定位Overlay的示例
2020/12/22 Vue.js
python操作mysql中文显示乱码的解决方法
2014/10/11 Python
Python对List中的元素排序的方法
2018/04/01 Python
快速解决安装python没有scripts文件夹的问题
2018/04/03 Python
python使用正则表达式来获取文件名的前缀方法
2018/10/21 Python
解决在pycharm中显示额外的 figure 窗口问题
2019/01/15 Python
python3 循环读取excel文件并写入json操作
2020/07/14 Python
解决python 执行shell命令无法获取返回值的问题
2020/12/05 Python
CSS3中使用RGBA设置透明度的示例
2015/08/04 HTML / CSS
Interflora澳大利亚:同日鲜花速递
2019/06/25 全球购物
回门宴新郎答谢词
2014/01/12 职场文书
工程安全员岗位职责
2014/03/09 职场文书
环境监测与治理技术专业求职信
2014/07/06 职场文书
实习推荐信格式模板
2015/03/27 职场文书
中秋节感想
2015/08/10 职场文书
使用HttpSessionListener监听器实战
2022/03/17 Java/Android
Win11查看设备管理器
2022/04/19 数码科技