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 相关文章推荐
些很实用且必用的小脚本代码
Jun 26 Javascript
JS中confirm,alert,prompt函数区别分析
Jan 17 Javascript
js中创建对象的几种方式示例介绍
Jan 26 Javascript
jQuery过滤选择器:not()方法使用介绍
Apr 20 Javascript
js实现异步循环实现代码
Feb 16 Javascript
jQuery技巧之让任何组件都支持类似DOM的事件管理
Apr 05 Javascript
JS轮播图中缓动函数的封装
Nov 25 Javascript
canvas实现钟表效果
Feb 13 Javascript
requireJS模块化实现返回顶部功能的方法详解
Oct 16 Javascript
在vue项目中引入高德地图及其UI组件的方法
Sep 04 Javascript
JS定时器如何实现提交成功提示功能
Jun 12 Javascript
vue cli3.0打包上线静态资源找不到路径的解决操作
Aug 03 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
fleaphp下不确定的多条件查询的巧妙解决方法
2008/09/11 PHP
php日期转时间戳,指定日期转换成时间戳
2012/07/17 PHP
Zend Studio去除编辑器的语法警告设置方法
2012/10/24 PHP
微信公众平台天气预报功能开发
2014/07/06 PHP
开启PHP Static 关键字之旅模式
2015/11/13 PHP
PHP如何获取当前主机、域名、网址、路径、端口等参数
2017/06/09 PHP
js图片延迟技术一般的思路与示例
2014/03/20 Javascript
纯javascript实现简单下拉刷新功能
2015/03/13 Javascript
跟我学习javascript的隐式强制转换
2015/11/16 Javascript
FullCalendar日历插件应用之数据展现(一)
2015/12/23 Javascript
javascript多物体运动实现方法分析
2016/01/08 Javascript
jquery 动态合并单元格的实现方法
2016/08/26 Javascript
nodejs爬虫遇到的乱码问题汇总
2017/04/07 NodeJs
Angular排序实例详解
2017/06/28 Javascript
js实现时钟定时器
2020/03/26 Javascript
JavaScript Window浏览器对象模型原理解析
2020/05/30 Javascript
[03:38]2014DOTA2西雅图国际邀请赛 VG战队巡礼
2014/07/07 DOTA
[01:11:35]Liquid vs LGD 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python在windows下实现备份程序实例
2014/07/04 Python
Python实现抓取页面上链接的简单爬虫分享
2015/01/21 Python
Python多线程结合队列下载百度音乐的方法
2015/07/27 Python
python爬虫爬取淘宝商品信息
2018/02/23 Python
实时获取Python的print输出流方法
2019/01/07 Python
python实现滑雪者小游戏
2020/02/22 Python
Python使用requests模块爬取百度翻译
2020/08/25 Python
python的链表基础知识点
2020/09/13 Python
CSS3实现类似翻书效果的过渡动画的示例代码
2019/09/06 HTML / CSS
天猫超市:阿里巴巴打造的网上超市
2016/11/02 全球购物
Gretna Green中文官网:苏格兰格林小镇
2019/10/16 全球购物
.net面试题
2016/09/17 面试题
GWebs公司笔试题
2012/05/04 面试题
GWT都有什么特性
2016/12/02 面试题
公司自我介绍演讲稿
2014/08/21 职场文书
中职三好学生事迹材料
2014/08/24 职场文书
Python趣味挑战之用pygame实现简单的金币旋转效果
2021/05/31 Python
阿里云ECS云服务器快照的概念以及如何使用
2022/04/21 Servers