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与C# Windows应用程序交互方法
Jun 29 Javascript
为指定元素增加样式的js代码
Dec 09 Javascript
动态的改变IFrame的高度实现IFrame自动伸展适应高度
Dec 28 Javascript
自己写了一个展开和收起的多更能型的js效果
Mar 05 Javascript
js字符串转换成xml对象并使用技巧解读
Apr 18 Javascript
浅析JQuery获取和设置Select选项的常用方法总结
Jul 04 Javascript
Document:getElementsByName()使用方法及示例
Oct 28 Javascript
深入理解JavaScript高级之词法作用域和作用域链
Dec 10 Javascript
深入理解Javascript箭头函数中的this
Feb 13 Javascript
如何开发出更好的JavaScript模块
Dec 22 Javascript
javascript异步处理与Jquery deferred对象用法总结
Jun 04 jQuery
express如何解决ajax跨域访问session失效问题详解
Jun 20 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
玩转图像函数库―常见图形操作
2006/09/03 PHP
PHP实现对文本数据库的常用操作方法实例演示
2014/07/04 PHP
PHP中把错误日志保存在系统日志中(Windows系统)
2015/06/23 PHP
PHP实现大数(浮点数)取余的方法
2017/02/18 PHP
一页面多XMLHttpRequest对象
2007/01/22 Javascript
用js实现上传图片前的预览(TX的面试题)
2007/08/14 Javascript
juqery 学习之三 选择器 可见性 元素属性
2010/11/25 Javascript
微信支付如何实现内置浏览器的H5页面支付
2015/09/25 Javascript
Jqgrid之强大的表格插件应用
2015/12/02 Javascript
js仿拉勾网首页穿墙广告效果
2017/03/08 Javascript
jQuery动态添加li标签并添加属性和绑定事件方法
2018/02/24 jQuery
vue.js数据绑定操作详解
2018/04/23 Javascript
webpack4之SplitChunksPlugin使用指南
2018/06/12 Javascript
js实现每日签到功能
2018/11/29 Javascript
vuex 动态注册方法 registerModule的实现
2019/07/03 Javascript
jQuery实现可编辑的表格
2019/12/11 jQuery
基于ant design日期控件使用_仅月份的操作
2020/10/27 Javascript
[52:27]2018DOTA2亚洲邀请赛 3.31 小组赛B组 paiN vs Secret
2018/04/01 DOTA
一篇不错的Python入门教程
2007/02/08 Python
python实现的守护进程(Daemon)用法实例
2015/06/02 Python
Python3实现购物车功能
2018/04/18 Python
python:接口间数据传递与调用方法
2018/12/17 Python
简单了解python的一些位运算技巧
2019/07/13 Python
Django 开发环境与生产环境的区分详解
2019/07/26 Python
Django学习之文件上传与下载
2019/10/06 Python
pytorch学习教程之自定义数据集
2020/11/10 Python
Python Selenium库的基本使用教程
2021/01/04 Python
美国医生配方营养补充剂供应商:Healthy Directions
2019/07/10 全球购物
英国100%防污和防水的靴子:Muck Boot Company
2020/09/08 全球购物
职业生涯规划怎么写
2013/12/29 职场文书
《口技》教学反思
2014/02/21 职场文书
市级文明单位申报材料
2014/05/07 职场文书
不忘国耻振兴中华演讲稿
2014/05/14 职场文书
财政局长个人总结
2015/03/04 职场文书
初中生思想道德自我评价
2015/03/09 职场文书
js前端面试常见浏览器缓存强缓存及协商缓存实例
2022/06/21 Javascript