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 相关文章推荐
Javascript结合css实现网页换肤功能
Nov 02 Javascript
ExtJS实现文件下载的方法实例
Nov 09 Javascript
javascript实时显示当天日期的方法
May 20 Javascript
jquery插件NProgress.js制作网页加载进度条
Jun 05 Javascript
javascript背景时钟实现方法
Jun 18 Javascript
jQuery实现的调整表格行tr上下顺序
Jan 10 Javascript
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
Apr 13 Javascript
基于pako.js实现gzip的压缩和解压功能示例
Jun 13 Javascript
vue项目中使用ueditor的实例讲解
Mar 05 Javascript
vue-cli 打包使用history模式的后端配置实例
Sep 20 Javascript
微信小程序自定义头部导航栏(组件化)
Nov 15 Javascript
vue实现前端分页完整代码
Jun 17 Javascript
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
超神学院:鹤熙已踏入神圣领域,实力不比凯莎弱
2020/03/02 国漫
PHP函数preg_match_all正则表达式的基本使用详细解析
2013/08/31 PHP
19个超实用的PHP代码片段
2014/03/14 PHP
ThinkPHP模板范围判断输出In标签与Range标签用法详解
2014/06/30 PHP
JavaScript 对象模型 执行模型
2010/10/15 Javascript
面向对象的Javascript之一(初识Javascript)
2012/01/20 Javascript
Node.js 制作实时多人游戏框架
2015/01/08 Javascript
Web表单提交之disabled问题js解决方法
2015/01/13 Javascript
学习JavaScript正则表达式
2015/11/13 Javascript
JavaScript常用数组算法小结
2016/02/13 Javascript
全面接触神奇的Bootstrap导航条实战篇
2016/08/01 Javascript
浅谈jquery高级方法描述与应用
2016/10/04 Javascript
javaScript生成支持中文带logo的二维码(jquery.qrcode.js)
2017/01/03 Javascript
JQuery元素快速查找与操作
2018/04/22 jQuery
vue-router 源码之实现一个简单的 vue-router
2018/07/02 Javascript
Bootstrap-table使用footerFormatter做统计列功能
2018/09/07 Javascript
微信小程序实现侧边栏分类
2019/10/21 Javascript
JS实现贪吃蛇游戏
2019/11/15 Javascript
详解vue3.0 diff算法的使用(超详细)
2020/07/01 Javascript
[01:00:04]DOTA2上海特级锦标赛B组小组赛#1 Alliance VS Spirit第二局
2016/02/26 DOTA
[52:20]DOTA2-DPC中国联赛正赛 SAG vs XGBO3 第一场 3月5日
2021/03/11 DOTA
django1.8使用表单上传文件的实现方法
2016/11/04 Python
python通过paramiko复制远程文件及文件目录到本地
2019/04/30 Python
对Python 检查文件名是否规范的实例详解
2019/06/10 Python
python Pandas库基础分析之时间序列的处理详解
2019/07/13 Python
pytorch方法测试详解——归一化(BatchNorm2d)
2020/01/15 Python
python 引用传递和值传递详解(实参,形参)
2020/06/05 Python
python boto和boto3操作bucket的示例
2020/10/30 Python
python RSA加密的示例
2020/12/09 Python
Shopee菲律宾:在线购买和出售
2019/11/25 全球购物
经典优秀个人求职信分享
2013/12/12 职场文书
函授教育个人学习的自我评价
2013/12/31 职场文书
如何写贫困证明申请书
2014/10/29 职场文书
入党积极分子群众意见
2015/06/01 职场文书
实习证明模板
2015/06/16 职场文书
写作指导:怎么书写竞聘演讲稿?
2019/07/04 职场文书