JS去除数组重复值的五种不同方法


Posted in Javascript onSeptember 06, 2013

今天工作遇到此问题,尝试多个方法不尽人意,故此写个博客来总结一下如何在js中去除重复元素。

Array类型并没有提供去重复的方法,如果要把数组的重复元素干掉,那得自己想办法:

方法1:

Array.prototype.method1 = function(){ 
      var arr[];  //定义一个临时数组 
      for(var i = 0; i < this.length; i++){  //循环遍历当前数组 
        //判断当前数组下标为i的元素是否已经保存到临时数组 
        //如果已保存,则跳过,否则将此元素保存到临时数组中 
        if(arr1.indexOf(this[i]) == -1){ 
          arr.push(this[i]); 
        } 
      } 
      return arr; 
    }

方法2:

Array.prototype.method2 = function(){ 
      var h{};  //定义一个hash表 
      var arr[]; //定义一个临时数组 
       
      for(var i = 0; i < this.length; i++){  //循环遍历当前数组 
        //对元素进行判断,看是否已经存在表中,如果存在则跳过,否则存入临时数组 
        if(!h[this[i]]){ 
          //存入hash表 
          h[this[i]] = true; 
          //把当前数组元素存入到临时数组中 
          arr.push(this[i]); 
        } 
      } 
      return arr; 
    }

方法3:

Array.prototype.method3 = function(){ 
      //直接定义结果数组 
      var arr[this[0]]; 
      for(var i = 1; i < this.length; i++){  //从数组第二项开始循环遍历此数组 
        //对元素进行判断: 
        //如果数组当前元素在此数组中第一次出现的位置不是i 
        //那么我们可以判断第i项元素是重复的,否则直接存入结果数组 
        if(this.indexOf(this[i]) == i){ 
          arr.push(this[i]); 
        } 
      } 
      return arr; 
     
    }

方法4:

Array.prototype.method4 = function(){ 
      //将数组进行排序 
      this.sort(); 
      //定义结果数组 
      var arr[this[0]]; 
      for(var i = 1; i < this.length; i++){  //从数组第二项开始循环遍历数组 
        //判断相邻两个元素是否相等,如果相等说明数据重复,否则将元素写入结果数组 
        if(this[i] !== arr[arr.length - 1]){ 
          arr.push(this[i]); 
        }       
      } 
      return arr; 
       
    }

例如:

var arr = [112,112,34,'你好',112,112,34,'你好','str','str1']; 
    alert(arr.method3());

方法1和方法3都用到了数组的indexOf()方法,此方法主要用来查找元素在数组中第一次出现的位置。比较浪费资源和时间。
方法2使用的是hash表,把已经出现过的元素通过下标形式写入到一个object内,下标的引用要比用数组indexOf()方法搜索节省时间。
方法4是先将数组排序,然后一次比较相邻的两个元素的值,排序使用的是js原生的sort()方法。
读者可以自行编写程序测试四种方法的效率如何。例如:首先利用随机函数生成一个50000长度的随机数数组,然后分别用四种方法进行执行,记录程序运行时间进行比较四种方法的优劣。

方法五、个人比较喜欢的一个函数

function unique(arr) {
  var result = [], isRepeated;
  for (var i = 0, len = arr.length; i < len; i++) {
    isRepeated = false;
    for (var j = 0, len = result.length; j < len; j++) {
      if (arr[i] == result[j]) {  
        isRepeated = true;
        break;
      }
    }
    if (!isRepeated) {
      result.push(arr[i]);
    }
  }
  return result;
}

总体思路是把数组元素逐个搬运到另一个数组,搬运的过程中检查这个元素是否有重复,如果有就直接丢掉。从嵌套循环就可以看出,这种方法效率极低。我们可以 用一个hashtable的结构记录已有的元素,这样就可以避免内层循环。恰好,在Javascript中实现hashtable是极为简单的,改进如下:

function unique(arr) {
  var result = [], hash = {};
  for (var i = 0, elem; (elem = arr[i]) != null; i++) {
    if (!hash[elem]) {
      result.push(elem);
      hash[elem] = true;
    }
  }
  return result;
}

完整测试代码

<script>
var h_hewenqiArray = new Array();
h_hewenqiArray[0] = "3water.com";
h_hewenqiArray[1] = "easysector";
h_hewenqiArray[2] = "3water.com";
h_hewenqiArray[3] = "keleyi";
h_hewenqiArray[4] = "keleyi";
h_hewenqiArray[5] = "三水点靠木";
h_hewenqiArray[6] = "3water.com";
h_hewenqiArray[7] = "hoverclock";
h_hewenqiArray[8] = "yestop";
h_hewenqiArray[9] = 163;
h_hewenqiArray[10] = "三水点靠木";
h_hewenqiArray[11] = 163;
h_hewenqiArray[12] = "hoverclock";
h_hewenqiArray[13] = "三水点靠木";

var h_arrayLength = h_hewenqiArray.length;
document.write("原始数组元素个数:"+h_arrayLength + "<br />");
for (var i = 0; i < h_arrayLength; i++)
{
document.write(h_hewenqiArray[i]+"<br />");
}


function hovercUnique(arr) {
var result = [], hash = {};
for (var i = 0, elem; (elem = arr[i]) != null; i++) {
if (!hash[elem]) {
result.push(elem);
hash[elem] = true;
}
}
return result;
//http://3water.com.com
}

var h_hewenqiResult = hovercUnique(h_hewenqiArray);

var h_resultLength = h_hewenqiResult.length;
document.write("<br />去重复后数组元素个数:" + h_resultLength + "<br />");
for (var i = 0; i < h_resultLength; i++) {
document.write(h_hewenqiResult[i] + "<br />");
} 
</script>

以下是其它网友的补充

/// <summary>2 /// 回车键按钮事件(此方法需要在页面加载完后执行,比如在Jquery中的ready中调用)--方法一 

/// </summary> 

/// 调用示例: 

/// var v_Array = new Array(1, 2, 3, 4, 5, 6, 7, 3, 3, 2, 2, 4, 2, 1, 1, 3); 

/// var v_ArrayResult = v_Array.deleteEle(); 

/// alert(v_ArrayResult); //返回结果:, 2, 3, 4, 5, 6, 7 

Array.prototype.deleteEle = function () { 

var o = {}, newArr = [], i, j; 

for (i = 0; i < this.length; i++) { 

if (typeof (o[this[i]]) == "undefined") { 

o[this[i]] = ""; 

} 

} 

for (j in o) { 

newArr.push(j) 

} 

return newArr; 

} 

/// <summary> 

/// 回车键按钮事件(此方法需要在页面加载完后执行,比如在Jquery中的ready中调用)--方法二 

/// </summary> 

/// 调用示例: 

/// var v_Array = new Array(1, 2, 3, 4, 5, 6, 7, 3, 3, 2, 2, 4, 2, 1, 1, 3); 

/// var v_ArrayResult = v_Array.deleteEleReg(); 

/// alert(v_ArrayResult); //返回结果:, 2, 3, 4, 5, 6, 7 

Array.prototype.deleteEleReg = function () { 

return this.reverse().join(",").match(/([^,]+)(?!.*\1)/ig).reverse(); 

} 

/// <summary> 

/// 回车键按钮事件(此方法需要在页面加载完后执行,比如在Jquery中的ready中调用)--方法三 

/// </summary> 

/// <param name="array">数组</param> 

/// 调用示例: 

/// var v_Array = new Array(1, 2, 3, 4, 5, 6, 7, 3, 3, 2, 2, 4, 2, 1, 1, 3); 

/// alert(unique(v_Array)); //返回结果:, 2, 3, 4, 5, 6, 7 

function deleteEleFunction(array) { 

var ret = [], record = {}, it, tmp, obj = "__object__", bak = [], i, len; 

var type = { 

"number": function (n) { return "__number__" + n; }, 

"string": function (n) { return "__string__" + n; }, 

"boolean": function (n) { return "__boolean__" + n; }, 

"undefined": function (n) { return "__undefined__"; }, 

"object": function (n) { 

return n === null ? "__null__" : obj in n ? n[obj] : (n[obj] = obj + bak.push(n)); 

} 

}; 

for (i = 0, len = array.length; i < len; i++) { 

it = array[i]; tmp = type[typeof it](it); 

if (!(tmp in record)) { ret.push(it); record[tmp] = true; } 

} 

for (i = 0, len = bak.length; i < len; delete bak[i++][obj]) { } 

return ret; 

}; 
/// <summary>< xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" /> 

/// 回车键按钮事件(此方法需要在页面加载完后执行,比如在Jquery中的ready中调用)--方法四 

/// </summary> 

/// 调用示例: 

/// var v_Array = new Array(1, 2, 3, 4, 5, 6, 7, 3, 3, 2, 2, 4, 2, 1, 1, 3); 

/// var v_ArrayResult = v_Array.deleteEleDis(); 

/// alert(v_ArrayResult); //返回结果:, 2, 3, 4, 5, 6, 7 

Array.prototype.deleteEleDis = function () { 

var a = [], b = []; 

for (var prop in this) { 

var d = this[prop]; 

if (d === a[prop]) continue; //防止循环到prototype 

if (b[d] != 1) { 

a.push(d); 

b[d] = 1; 

} 

} 

return a; 

}
Javascript 相关文章推荐
jquery动态改变onclick属性导致失效的问题解决方法
Dec 04 Javascript
js 设置缓存及获取设置的缓存
May 08 Javascript
教你在heroku云平台上部署Node.js应用
Jul 30 Javascript
jQuery实现大转盘抽奖活动仿QQ音乐代码分享
Aug 21 Javascript
jquery实现美观的导航菜单鼠标提示特效代码
Sep 06 Javascript
ECMAScript6快速入手攻略
Jul 18 Javascript
原生js轮播(仿慕课网)
Feb 15 Javascript
深入浅析Vue不同场景下组件间的数据交流
Aug 15 Javascript
解决vue-cli项目webpack打包后iconfont文件路径的问题
Sep 01 Javascript
微信小程序 高德地图路线规划实现过程详解
Aug 05 Javascript
原生js实现表格循环滚动
Nov 24 Javascript
vue使用element-ui按需引入
May 20 Vue.js
JavaScript判断密码强度(自写代码)
Sep 06 #Javascript
js实现连续英文字符自动换行兼容ie6 ie7和firefox
Sep 06 #Javascript
让网页跳转到指定位置的jquery代码非书签
Sep 06 #Javascript
jquery中prop()方法和attr()方法的区别浅析
Sep 06 #Javascript
CheckBoxList多选样式jquery、C#获取选择项
Sep 06 #Javascript
jquery阻止冒泡事件使用模拟事件
Sep 06 #Javascript
Jquery的hover方法让鼠标经过li时背景变色
Sep 06 #Javascript
You might like
业余方法DIY电子管FM收音机
2021/03/02 无线电
PHP数据库操作面向对象的优点
2006/10/09 PHP
如何使用动态共享对象的模式来安装PHP
2006/10/09 PHP
一步一步学习PHP(8) php 数组
2010/03/05 PHP
php实现单链表的实例代码
2013/03/22 PHP
19个超实用的PHP代码片段
2014/03/14 PHP
php限制文件下载速度的代码
2015/10/20 PHP
初试jQuery EasyUI 使用介绍
2010/04/01 Javascript
简约JS日历控件 实例代码
2013/07/12 Javascript
页面实时更新时间的JS实例代码
2013/12/18 Javascript
BootStrap 智能表单实战系列(十)自动完成组件的支持
2016/06/13 Javascript
jQuery事件处理的特征(事件命名机制)
2016/08/23 Javascript
Angular2学习笔记——详解路由器模型(Router)
2016/12/02 Javascript
微信小程序 两种滑动方式(横向滑动,竖向滑动)详细及实例代码
2017/01/13 Javascript
JQuery查找子元素find()和遍历集合each的方法总结
2017/03/07 Javascript
详解用vue-cli来搭建vue项目和webpack
2017/04/20 Javascript
seajs中最常用的7个功能、配置示例
2017/10/10 Javascript
最实用的JS数组函数整理
2017/12/05 Javascript
JS+CSS实现滚动数字时钟效果
2017/12/25 Javascript
Angular-UI Bootstrap组件实现警报功能
2018/07/16 Javascript
jQuery常见的遍历DOM操作详解
2018/09/05 jQuery
[58:21]DOTA2亚洲邀请赛 4.3 突围赛 Liquid vs VGJ.T 第二场
2018/04/04 DOTA
Python简单日志处理类分享
2015/02/14 Python
python实现字典(dict)和字符串(string)的相互转换方法
2017/03/01 Python
Python通过matplotlib画双层饼图及环形图简单示例
2017/12/15 Python
python微信跳一跳系列之自动计算跳一跳距离
2018/02/26 Python
django DRF图片路径问题的解决方法
2018/09/10 Python
Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算
2018/12/28 Python
Python数据可视化教程之Matplotlib实现各种图表实例
2019/01/13 Python
海淘零差价,宝贝全球购: 宝贝格子
2016/08/24 全球购物
现代生活方式的家具和装饰:Dot & Bo
2018/12/26 全球购物
优秀教师先进事迹
2014/01/22 职场文书
2014国庆黄金周超市促销活动方案
2014/09/21 职场文书
四年级数学上册教学计划
2015/01/20 职场文书
毕业生爱心捐书倡议书
2015/04/27 职场文书
机器人瓦力观后感
2015/06/12 职场文书