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 组件之旅(四):测试 JavaScript 组件
Oct 28 Javascript
div+css布局的图片连续滚动js实现代码
May 04 Javascript
js getElementsByTagName的简写方式
Jun 27 Javascript
AeroWindow 基于JQuery的弹出窗口插件
Jun 27 Javascript
js实现文章文字大小字号功能完整实例
Nov 01 Javascript
JS实现支持Ajax验证的表单插件
Mar 24 Javascript
javaScript中定义类或对象的五种方式总结
Dec 04 Javascript
基于daterangepicker日历插件使用参数注意的问题
Aug 10 Javascript
使用vue-resource进行数据交互的实例
Sep 02 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
Aug 09 jQuery
JavaScript实现动态添加、移除元素或属性的方法分析
Jan 03 Javascript
微信小程序中网络请求缓存的解决方法
Dec 29 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
复杂检索数据并分页显示的处理方法
2006/10/09 PHP
php设计模式 Bridge (桥接模式)
2011/06/26 PHP
php文件上传简单实现方法
2015/01/24 PHP
php简单获取复选框值的方法
2016/05/11 PHP
PHP入门教程之会话控制技巧(cookie与session)
2016/09/11 PHP
PHP实现的XML操作类【XML Library】
2016/12/29 PHP
详解PHP文件的自动加载(autoloading)
2018/02/04 PHP
用document.documentElement取代document.body的原因分析
2009/11/12 Javascript
javascript编码的几个方法详细介绍
2013/01/06 Javascript
jquery清空textarea等输入框实现代码
2013/04/22 Javascript
js中的时间转换—毫秒转换成日期时间的示例代码
2014/01/26 Javascript
js全选实现和判断是否有复选框选中的方法
2015/02/17 Javascript
详解JavaScript的策略模式编程
2015/06/24 Javascript
基于jquery fly插件实现加入购物车抛物线动画效果
2016/04/05 Javascript
基于BootStrap环境写jQuery tabs插件
2016/07/12 Javascript
JavaScript之filter_动力节点Java学院整理
2017/06/28 Javascript
WebSocket的通信过程与实现方法详解
2018/04/29 Javascript
详解如何在nuxt中添加proxyTable代理
2018/08/10 Javascript
详解SPA中前端路由基本原理与实现方式
2018/09/12 Javascript
vue实现抖音时间转盘
2019/09/08 Javascript
Python线程详解
2015/06/24 Python
python 排序算法总结及实例详解
2016/09/28 Python
Python 自动刷博客浏览量实例代码
2017/06/14 Python
python爬取亚马逊书籍信息代码分享
2017/12/09 Python
解决vscode python print 输出窗口中文乱码的问题
2018/12/03 Python
PyQT5 QTableView显示绑定数据的实例详解
2019/06/25 Python
Python爬取爱奇艺电影信息代码实例
2019/11/26 Python
Python PIL库图片灰化处理
2020/04/07 Python
css3 border-image使用说明
2010/06/23 HTML / CSS
HTML5中drawImage用法分析
2014/12/01 HTML / CSS
法国大使拉杆箱官网:DELSEY Paris
2018/03/20 全球购物
英国排名第一的在线宠物用品商店:Monster Pet Supplies
2018/05/20 全球购物
工厂仓库管理员岗位职责
2015/04/09 职场文书
学校党支部承诺书
2015/04/30 职场文书
基于Redis位图实现用户签到功能
2021/05/08 Redis
如何基于python实现单目三维重建详解
2022/06/25 Python