这9种数组去重方法,直到今天,我才彻底弄懂

目录

方法一、最常使用,也最容易想到的思路( ES5 ):

方法二、ES6 Set() 去重( ES6 中最常用)

方法三、使用 indexOf 去重

方法四、使用 sort() 排序去重

方法五、使用 includes() 去重

方法六、利用 hasOwnProperty() 去重

方法七、利用 filter() + indexOf() 去重

方法八、利用 Map 数据结构去重 

方法九、 利用 reduce() + includes() 去重


数组去重是我们经常会遇到的题目,我总结了9种方法来实现这个功能,一起来看看吧!

注:在下面的示例中,我采用的数据非常特殊,出现了很多数据类型,如: {} 、 NaN、true 等。在实际应用场景中,不会有那么多特殊的数据,一般是正常的数据。这里只是为了突出它们的区别。

方法一、最常使用,也最容易想到的思路( ES5 ):

使用for循环,双层遍历,当内层循环的值等于外层循环的值,则将内层循环的值,使用 splice() 删除

/*
      方法一:最常使用,也最容易想到的思路:
        使用for循环,双层遍历,
        当内层循环的值等于外层循环的值,则将内层循环的值,使用splice删除
    */
    function unique1(arr){
      for(let i=0;i<arr.length;i++){
        for(let j=i+1;j<arr.length;j++){
          // 如果二者相同,则进行删除
          if(arr[i] === arr[j]){
            // 删除下标为j的这个元素
            arr.splice(j,1)
            // splice方法会改变元素组的大小,所以每删除一个元素,这里要j--
            j--
          }
        }
      }
      return arr
    }

    var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
    console.log(unique1(arr)) 

打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是15,其中,重复的 {} 、NaN 并没有被删除。原因是 {} 不等于 {} ,NaN 不等于 NaN

上述代码的简化版本:只要 var newArr = [...new Set(arr)] 这一行足够,但是重复的 {} 、NaN 并没有被删除。

var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
var newArr = [...new Set(arr)]
console.log(newArr)

方法二、ES6 Set() 去重( ES6 中最常用)

使用 Set() 将 arr 去重后,再转换为数组

    /*
      方法二:ES6的Set去重
      使用Set将arr去重后,再转换为数组
    */
    function unique2(arr){
      return Array.from(new Set(arr))
    }
    var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
    console.log("原数组的长度是:",arr.length)
    console.log(unique2(arr)) 

打印结果如下:可以看出,原数组的长度是24,去重之后,数组长度是14,其中,重复的 {} 没有被去除

方法三、使用 indexOf 去重

indexOf() 方法返回某个指定的字符串值在字符串中首次出现的位置,如果没有找到匹配的字符串则返回 -1。注意: indexOf() 方法,在判断是否匹配时,区分大小写。

可以利用 indexOf 来实现去重

    /*
      方法三:indexOf() 方法返回某个指定的字符串值在字符串中首次出现的位置
    */
    function unique3(arr){
      // 新建一个空数组,存放去重之后的数组元素
      var array = []
      for(var i=0;i<arr.length;i++){
        // 如果新数组array中,没有旧数组arr的下标为i对应的元素,则添加到新数组中
        // 注意要使用全等符号
        if(array.indexOf(arr[i]) === -1){
          array.push(arr[i])
        }
      }
      return array
    }
    var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
    console.log("原数组的长度是:",arr.length)
    console.log(unique3(arr)) 

打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是15,其中,重复的 {}、NaN 并没有被删除。

方法四、使用 sort() 排序去重

    /*
      方法四:使用sort()排序,比较前后相邻元素是否相同
    */
    function unique4(arr){
      arr.sort()
      // 排序之后,第一个元素要么是唯一的,要么是和后面的元素重复
      // 把旧数组的第一个元素之间添加到新数组array中
      var array = [arr[0]]
      for(var i=1;i<arr.length;i++){
        if(arr[i] !== arr[i-1]){
          array.push(arr[i])
        }
      }
      return array
    }
    var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
    console.log(arr.sort())
    console.log("原数组的长度是:",arr.length)
    console.log(unique4(arr))

注意:在排序的时候,布尔值 true 是无法判断该放在哪个后面的,所以后面去重时,由于排序导致的问题,重复的 “true” 没有被完全去除。此外,重复的 {} 和 NaN 也没有被去除。

方法五、使用 includes() 去重

includes() 方法用于判断字符串是否包含指定的子字符串。如果找到匹配的字符串则返回 true ,否则返回 false 。注意: includes() 方法区分大小写。

    /*
      方法五:使用includes
    */
    function unique5(arr){
      // 新建一个空数组,存放去重之后的数组元素
      var array = []
      for(var i=0;i<arr.length;i++){
        //includes 判断数组是否有某个值
        if(!array.includes(arr[i])){
          array.push(arr[i])
        }
      }
      return array
    }
    var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
    console.log("原数组的长度是:",arr.length)
    console.log(unique5(arr)) 

打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是14,其中,重复的 {} 并没有被删除。

方法六、利用 hasOwnProperty() 去重

hasOwnProperty() 方法用于检测一个对象是否含有特定的自身属性,返回一个布尔值。typeof item + item 是数组的元素 item 的类型与值拼接在一起,作为 obj 对象的属性,这个属性是唯一的,在遍历过程中,如果 obj 中有这个属性,则不会添加到 obj 对象上,达到去重的效果。

    /*
      方法六:利用hasOwnProperty
    */
    function unique6(arr){
      var obj = {}
      return arr.filter(function(item,index,arr){
        //typeof item + item是数组的元素item的类型与值拼接在一起,作为obj对象的属性,这个属性是唯一的
        //如果obj中有这个属性,则不会添加到obj对象上,达到去重的效果
        return obj.hasOwnProperty(typeof item + item)?false:(obj[typeof item +item] = true)
      })
    }
    var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
    console.log("原数组的长度是:",arr.length)
    console.log(unique6(arr)) 

 打印结果如下:可以发现,所有的元素都去重了。

方法七、利用 filter() + indexOf() 去重

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

注意: filter() 不会对空数组进行检测, filter() 不会改变原始数组。

    /*
      方法七:利用filter + indexOf
    */
    function unique7(arr){
      return arr.filter(function(item,index,arr){
        // arr.indexOf(item,0)是元素item首次出现的位置,
        // 如果与当前的索引值index相等,说明该元素item之前从未出现过
        return arr.indexOf(item,0) === index
      })
    }
    var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
    console.log("原数组的长度是:",arr.length)
    console.log(unique7(arr)) 

打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是13,其中,重复的 {} 并没有被删除。NaN 元素不在去重后的数组中了。

方法八、利用 Map 数据结构去重 

set() 方法为 Map() 对象添加或更新一个指定了键( key )和值( value )的(新)键值对。

创建一个空 Map 数据结构,遍历需要去重的数组,把数组的每一个元素作为 key 存到 Map 中。由于 Map 中不会出现相同的 key 值,所以最终得到的就是去重后的结果。 

    /*
      方法八: 利用Map数据结构去重
    */ 
    function unique8(arr){
      let map = new Map()
      let array = []
      for(let i = 0;i<arr.length;i++){
        // 如果map对象中含有键arr[i]
        if(map.has(arr[i])){
          // 就用set()方法,将该键对应的value设置为true
          map.set(arr[i],true)
        }else{
          map.set(arr[i],false)
          array.push(arr[i])
        }
      }
      return array
    }

    var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
    console.log("原数组的长度是:",arr.length)
    console.log(unique8(arr)) 

打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是14,其中,重复的 {} 并没有被删除。 

方法九、 利用 reduce() + includes() 去重

 

    /*
      方法九:利用reduce+includes
    */
    function unique9(arr){
      return arr.reduce((prev,curr) => prev.includes(curr) ? prev : [...prev,curr],[])
    }
    var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
    console.log("原数组的长度是:",arr.length)
    console.log(unique9(arr)) 

打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是14,其中,重复的 {} 并没有被删除。 


总结了这么多数组去重的方法,你学废了吗?

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唯一的阿金

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值