javascript数组去掉重复

  总得来说面试的过程还是收获了不少,主要是认清自己的差距到底有多大,知识面到底有多窄,适当打击一下自信心还是有必要的。在这里做一次全面的总结,关于javascript的数组去重问题。

  考虑一个问题由简到繁相对容易接受一点,首先假设要去重的数组是比较简单的,例如:

  

复制代码 代码如下:

  var arr=[1,2,2,3,'5',6,5,'',' ']

  这个数组只包含了数字,字符串两种类型。我们给数组原型上面添加去重的方法distinct,用第一种很容易想到的方法来实现,当然也是很笨很直接的,把这个数组复制一份然后循环两个数组,对比当前值与后面所有的值是否相等,如果与后面所有值都不等则把该值存到新数组里,如此最后再返回该新数组。方法如下:

  

复制代码 代码如下:

  //第一种方法

  Array.prototype.distinct=function(){

  var clone,newArr=[],n=0;

  if(this.length<2)return;

  clone=this;

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

  for(var j=i+1,len2=clone.length;j<len2;j++){

  if(this[i]!==clone[j]){

  n++;

  }

  }

  if(n==(len-i-1)){

  newArr.push(this[i])

  }

  n=0;

  }

  return newArr;

  }

  console.log([1,2,2,3,'5',6,5,'',' '].distinct());

  /*获得被check的radio的值*/

  function GetRadioValue(RadioName){

  var obj;

  obj=document.getElementsByName(RadioName);

  if(obj!=null){

  var i;

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

  if(obj[i].checked){

  return obj[i].value;

  }

  }

  }

  return null;

  }

  /*设置被选中属性*/

  function SetRadioCheck(RadioName,i){

  var obj;

  obj=document.getElementsByName(RadioName);

  obj[i].setAttribute("checked","checked");

  }

  基本可以满足我们的需求,对这样简单的类型比较确实不用费太多的脑经,但如果数组很长呢?如此遍历数组,数组长度为n,那么时间复杂度为n*n。显然该方法性能还有待提升。接下来是第二种方法,用到数组排序,在排序的过程去除重复的值。

  

复制代码 代码如下:

  //第二种方法

  Array.prototype.distinct=function(){

  var newArr=this.concat().sort(),self=this;

  newArr.sort(function(a,b){

  var n;

  if(a===b){

  n=self.indexOf(a);

  self.splice(n,1);

  }

  });

  return self;

  }

  console.log([1,2,2,3,'5',6,5,6,6,15,5,'5',5,'',' '].distinct());

  这样代码看起来似乎短了很多,甚至连一个for循环都没有,但是sort得效率也高不到哪里去。再来看看第三种实现方法,用到的对象属性不会重名的原理

  

复制代码 代码如下:

  //第三种方法

  Array.prototype.distinct=function(){

  var newArr=[],obj={};

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

  if(!obj[this[i]]){

  newArr.push(this[i]);

  obj[this[i]]='new';

  }

  }

  return newArr;

  }

  console.log([1,2,2,3,'5',6,5,6,6,15,5,'5',5,'',' '].distinct());

  第三种方法运行看下结果,会发现跟上面的方法实现的结果不一致,细看原来它把数字5和字符串5当成重复的值给去掉了。看来类型必须保存起来然后再判断是否相等,这样便有了下面的第三种方法的补充版

  

复制代码 代码如下:

  //第三种方法补充版

  Array.prototype.distinct=function(){

  var newArr=[],obj={};

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

  if(!obj[typeof(this[i])+this[i]]){

  newArr.push(this[i]);

  obj[typeof(this[i])+this[i]]='new';

  }

  }

  return newArr;

  }

  上面举的例子是很简单的类型,我们拿更复杂的类型来测试一下

  

复制代码 代码如下:

  console.log([1,null,2,{a:'vc'},{},'5',6,5,6,{a:'vv'},15,5,'5',5,'',' ',[1],[1],[1,2],,].distinct());

  发现{a:'vc'},{},{a:'vv'}这些不同的对象还是会被剔除掉,如果数组里面有对象则要继续遍历对象里面的属性和值,继续第三种方法的加强

  

复制代码 代码如下:

  //第三种方法加强版

  Array.prototype.distinct=function(){

  var sameObj=function(a,b){

  var tag = true;

  if(!a||!b)return false;

  for(var x in a){

  if(!b[x])

  return false;

  if(typeof(a[x])==='object'){

  tag=sameObj(a[x],b[x]);

  }else{

  if(a[x]!==b[x])

  return false;

  }

  }

  return tag;

  }

  var newArr=[],obj={};

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

  if(!sameObj(obj[typeof(this[i])+this[i]],this[i])){

  newArr.push(this[i]);

  obj[typeof(this[i])+this[i]]=this[i];

  }

  }

  return newArr;

  }

  用上面的例子测试发现基本木有问题,当然测试还可以更加变态更加纠缠,这里就不去深究了,目前来看此篇方法在网上属于比较齐全的,如果有更好更完善的方法请不吝赐教。