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 相关文章推荐
比较简单实用的使用正则三种版本的js去空格处理方法
Nov 18 Javascript
JavaScript link方法入门实例(给字符串加上超链接)
Oct 17 Javascript
基于jquery实现的自动补全功能
Mar 12 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(二)之数据支持json字符串、list集合
Aug 11 Javascript
angularjs实现文字上下无缝滚动特效代码
Sep 04 Javascript
JavaScript 拖拽实例代码
Sep 21 Javascript
vue 数组和对象不能直接赋值情况和解决方法(推荐)
Oct 25 Javascript
vscode下vue项目中eslint的使用方法
Jan 13 Javascript
JavaScript 扩展运算符用法实例小结【基于ES6】
Jun 17 Javascript
js实现for循环跳过undefined值示例
Jul 02 Javascript
如何利用node.js开发一个生成逐帧动画的小工具
Dec 01 Javascript
node.JS的crypto加密模块使用方法详解(MD5,AES,Hmac,Diffie-Hellman加密)
Feb 06 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
PHP中list()函数用法实例简析
2016/01/08 PHP
php 实现进制相互转换
2016/04/07 PHP
解决php-fpm.service not found问题的办法
2017/06/06 PHP
地址栏上的一段语句,改变页面的风格。(教程)
2008/04/02 Javascript
JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(六)
2012/04/07 Javascript
node.js中的fs.fchmod方法使用说明
2014/12/16 Javascript
用JavaScript来美化HTML的select标签的下拉列表效果
2015/11/17 Javascript
Vue 2.X的状态管理vuex记录详解
2017/03/23 Javascript
JS实现侧边栏鼠标经过弹出框+缓冲效果
2017/03/29 Javascript
AngularJS  ng-repeat遍历输出的用法
2017/06/19 Javascript
基于jquery实现多选下拉列表
2017/08/02 jQuery
微信小程序三级联动选择器使用方法
2020/05/19 Javascript
基于Vue实现拖拽效果
2018/04/27 Javascript
node puppeteer(headless chrome)实现网站登录
2018/05/09 Javascript
SVG实现时钟效果
2018/07/17 Javascript
微信小程序上传多图到服务器并获取返回的路径
2019/05/05 Javascript
vue实现动态按钮功能
2019/05/13 Javascript
Vue 动态添加路由及生成菜单的方法示例
2019/06/20 Javascript
Vue中fragment.js使用方法小结
2020/02/17 Javascript
微信小程序订阅消息(java后端实现)开发
2020/06/01 Javascript
Javascript中的奇葩知识,你知道吗?
2021/01/25 Javascript
Flask框架web开发之零基础入门
2018/12/10 Python
python实现可变变量名方法详解
2019/07/01 Python
pandas计算最大连续间隔的方法
2019/07/04 Python
Python原始套接字编程实例解析
2020/01/29 Python
tensorflow2.0保存和恢复模型3种方法
2020/02/03 Python
通过python调用adb命令对App进行性能测试方式
2020/04/23 Python
判断Threading.start新线程是否执行完毕的实例
2020/05/02 Python
python 实现朴素贝叶斯算法的示例
2020/09/30 Python
Django和Ueditor自定义存储上传文件的文件名
2021/02/25 Python
消防标语大全
2014/06/07 职场文书
学校安全生产月活动总结
2014/07/05 职场文书
酒店人事专员岗位职责
2015/04/07 职场文书
高中运动会前导词
2015/07/20 职场文书
pytorch 中autograd.grad()函数的用法说明
2021/05/12 Python
Vue实现跑马灯样式文字横向滚动
2021/11/23 Vue.js