JS-数组去重

数组去重

这里只考虑元素均为基本数据类型

[1,1,'1',2,'1'] => [1,'1',2]

方法1:双层循环

结果数组res中放唯一元素,然后arr每个元素与res每个元素比较,如果相等,跳出内部循环,如果不等,内部循环结束肯定有j==res.length,放入arr[i]即可

function unique(arr){
  var res = []
  for(var i=0;i<arr.length;i++){
    for(var j=0;j<res.length;j++){
      if(arr[i]===res[j])
        break
    }
    if(j==res.length){
      res.push(arr[i])
    }
  }
  return res
}

改进:双层循环的另一种方法是结合splice方法,直接在原数组删除重复元素,不需要在弄一个空数组,个人觉得这种方法比上面更好理解

function unique(arr){
  for(var i=0;i<arr.length;i++){
    for(var j=i+1;j<arr.length;j++){
      if(arr[i]===arr[j]){
        arr.splice(j,1)  //splice是能改变原数组的,slice不行
        j--  //如果有重复元素,删除之后一定要j--
      }
    }
  }
  return arr
}

这两种方法大同小异,都不能对NaN和对象去重,其他基本数据类型没问题

方法2:indexof改进

其实就是利用indexof去掉方法1中的内部循环,思想还是一样的,还可以用数组的includes方法

function unique(arr){
  var res = []
  for(var i=0;i<arr.length;i++){
    if(res.indexOf(arr[i])==-1){
      res.push(arr[i])
    }
  }
  return res
}

不能对NaN和对象去重,其他基本数据类型没问题

改进:用for遍历数组还可以换成filter方法,直接修改原数组

function unique(arr){
  return arr.filter(function(cur,index){
    return arr.indexOf(cur) == index
  })
}

方法3:Object键值对

把数组元素的值作为对象obj的键名,用对象的hasOwnProperty方法判断obj有没有这个键,没有的话就把元素放进res中,但是对象的键名都是字符串,数组元素1和’1’作为键名时,是一样的,故键名要修改,加上元素的类型

function unique(arr){
  var obj = {}
  var res = []
  for(var i=0;i<arr.length;i++){
    if(!obj.hasOwnProperty(typeof arr[i]+arr[i])){  //obj没有当前元素构成的键名
      res.push(arr[i])
      obj[typeof arr[i]+arr[i]] = true  //键名是typeof arr[i]+arr[i]
    }
  }
  return res
}

这种办法能对NaN去重,对象无法区分,只留最前面的那一个!
因为任何数组typeof arr[i]+arr[i]结果都是[object Object]

方法4:ES6 Set/Map数据结构

Set—没有重复值的数组

function unique(arr){
  return [...new Set(arr)]
}

Map—键名可以不是字符串的对象,用map其实就是简化了方法3,对象的键名不需要再加上类型了,每一步含义其实都是相同的

function unique(arr){
  var res = []
  var map = new Map()
  for(var i=0;i<arr.length;i++){
    if(!map.has(arr[i])){  //map没有当前元素键名
      res.push(arr[i])
      map.set(arr[i],true)
    }
  }
  return res
}

这两种方法,NaN去重,对象不去重,其他基本数据类型可以

方法5:sort排序(有局限性)

对数组sort排序,相同的值肯定挨着,遍历数组,当前值和前一个值不同的时候,把当前值放入res中。

如果遇到如下情况肯定就不能得到正确结果了,所以我觉得sort最好用在数组元素均为数字/字符串的情况

var a = [1,1,2,'1',1,'1']
console.log(a.sort());  //[1,1,'1',1,'1',2]
function unique(arr){
  var sortedArr = arr.concat().sort()  //先复制一份输入数组在排序,避免破坏原数组
  var res = []
  for (var i = 0; i < arr.length; i++){
    if(!i||sortedArr[i]!==sortedArr[i-1]){ //i=0时,要把元素加入数组
      res.push(sortedArr[i])
    }
  }
  return res
}

var array = ['1', '1', '1', '1', '2', '1']
console.log(unique(array)); //['1','2']
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值