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 25 Javascript
javascript引用对象的方法
Jan 11 Javascript
理解Javascript_02_理解undefined和null
Oct 11 Javascript
JavaScript中的property和attribute介绍
Dec 26 Javascript
jquery js 重置表单 reset()具体实现代码
Aug 05 Javascript
jQuery中andSelf()方法用法实例
Jan 08 Javascript
JavaScript实现LI列表数据绑定的方法
Aug 04 Javascript
jQuery EasyUI提交表单验证
Jul 19 Javascript
node.js学习之断言assert的使用示例
Sep 28 Javascript
Node.js 使用AngularJS的方法示例
May 11 Javascript
详解vue填坑之解决部分浏览器不支持pushState方法
Jul 12 Javascript
JavaScript setTimeout()基本用法有哪些
Nov 04 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修改xml文档内容的方法
2015/01/23 PHP
php动态变量定义及使用
2015/06/10 PHP
Laravel 中使用简单的方法跟踪用户是否在线(推荐)
2019/10/30 PHP
另类调用flash无须激活的方法
2006/12/27 Javascript
原生Js实现按的数据源均分时间点幻灯片效果(已封装)
2010/12/28 Javascript
js实现一个省市区三级联动选择框代码分享
2013/03/06 Javascript
Extjs4 类的定义和扩展实例
2013/06/28 Javascript
使用js修改客户端注册表的方法
2013/08/09 Javascript
关闭浏览器窗口弹出提示框并且可以控制其失效
2014/04/15 Javascript
javaScript如何处理从java后台返回的list
2014/04/24 Javascript
使用jquery获取url以及jquery获取url参数的实现方法
2016/05/25 Javascript
js将json格式的对象拼接成复杂的url参数方法
2016/05/25 Javascript
js实现碰撞检测特效代码分享
2016/10/16 Javascript
详解vue-validator(vue验证器)
2017/01/16 Javascript
Vue实例中生命周期created和mounted的区别详解
2017/08/25 Javascript
通过jquery toggleClass()属性制作文章段落更改背景颜色
2018/05/21 jQuery
vue中vee validate表单校验的几种基本使用
2018/06/25 Javascript
使用NestJS开发Node.js应用的方法
2018/12/03 Javascript
JS实现获取自定义属性data值的方法示例
2018/12/19 Javascript
js Array.slice的8种不同用法示例
2019/07/10 Javascript
Vue.js如何使用Socket.IO的示例代码
2019/09/05 Javascript
JavaScript中判断为整数的多种方式及保留两位小数的方法
2019/09/09 Javascript
javascript严格模式详解(含严格模式与非严格模式的区别)
2019/11/12 Javascript
Python学习笔记(一)(基础入门之环境搭建)
2014/06/05 Python
Python使用bs4获取58同城城市分类的方法
2015/07/08 Python
python学习之编写查询ip程序
2016/02/27 Python
PyQt5每天必学之拖放事件
2020/08/27 Python
如何在python中实现随机选择
2019/11/02 Python
Python利用matplotlib绘制约数个数统计图示例
2019/11/26 Python
详解使用HTML5 Canvas创建动态粒子网格动画
2016/12/14 HTML / CSS
新加坡鲜花速递/新加坡网上花店:Ferns N Petals
2020/08/29 全球购物
庆中秋节主题活动方案
2014/02/03 职场文书
教师党员公开承诺书
2014/03/25 职场文书
公共机构节能宣传周活动总结
2014/07/09 职场文书
教师正风肃纪剖析材料
2014/10/20 职场文书
MySql重置root密码 --skip-grant-tables
2022/04/11 MySQL