数组去重的N种方法(面试必备)

本文探讨了面试中常见的数组去重问题,包括使用ES6语法、双重循环、利用下标、排序以及数据结构等多种方法,并提示部分方法可能存在兼容性问题。文章鼓励读者分享更多去重技巧进行交流学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在面试的过程中,经常被问到Array (数组)如何去重,回答的好不好直接可以影响到offer拿不拿的到,还可以为作为一个谈薪资的筹码。(还有其他的可以提供一起来交流学习)

数组去重的N个方法:

通过ES6中的Set语法(会有兼容性问题):

 function unique (arr) {
      return Array.from( new Set(arr))
    }  
    function unique1 (arr) {
      return [ ...new Set(arr)] 
    }
   var arr  = [ 1, 2, '2', 'a', 'b', '2', 3, 5, 'a', '{}','{}']
    console.log(unique(arr), 'unique', unique1(arr))
    // [1, 2, "2", "a", "b", 3, 5, "{}"] 结果是一样的

利用ES6中indexOf() + fifter()方法去重:

function unique (arr) {
      return Array.isArray(arr) && (
        arr.filter((item, index, arr) => {
        // indexOf()会找当前元素item在数组中的第一次出现时的下标
          return arr.indexOf(item) === index
        })
      )
    }  
   var arr  = [ 1, 2, '2', 'a', 'b', '2', 3, 5, 'a', '{}','{}']
    console.log(unique(arr))
    // [1, 2, "2", "a", "b", 3, 5, "{}"]

双重for循环+splice()改变原数组的方法去重(⚠️:对于数组类型(Number),用于排序):

 function unique (arr) {
     if (!Array.isArray(arr)) return
      let newArr = []
      for( let i = 0; i < arr.length; i ++) {
        for (let j = i+1; j < arr.length; j++) {
          // 用数组当前项与其他项对比进行**全等**比较,相同的就删除
          if (arr[i] === arr[j]){
            arr.splice(j,1)
            // 有相同项时不一定全部对比完,此时已经循环了一次j++,为了防止遗漏,需要回退一次
            j--
          }
        }
      }
      return arr
    }  
   var arr  = [ 1, 2, '2', 'a', 'b', '2', 3, 5, 'a', '{}','{}']
    console.log(unique(arr))
    // [1, 2, "2", "a", "b", 3, 5, "{}"]

利用for循环+ indexOf()找下标的方法去重:

function unique (arr) {
     if (!Array.isArray(arr)) return
      let newArr = []
      for( let i = 0; i < arr.length; i ++) {
        // 通过indexOf()判断当前元素在不在新的数组中,不在的话,就添加上去
       if (newArr.indexOf(arr[i]) === -1) {
        newArr.push(arr[i])
       }
      }
      return newArr
    }  
   var arr  = [ 1, 2, '2', 'a', 'b', '2', 3, 3,5, 'a', '{}','{}']
    console.log(unique(arr))
    // [1, 2, "2", "a", "b", 3, 5, "{}"]

利用for循环+ includes()找下标的方法去重(同上,判断返回结果不一样):

 function unique (arr) {
     if (!Array.isArray(arr)) return
      let newArr = []
      for( let i = 0; i < arr.length; i ++) {
        // 通过includes()判断当前元素在不在新的数组中(返回布尔值),不在的话,就添加上去
       if (!newArr.includes(arr[i])) {
        newArr.push(arr[i])
       }
      }
      return newArr
    }  
   var arr  = [ 1, 2, '2', 'a', 'b', '2', 3, 3,5, 'a', '{}','{}']
    console.log(unique(arr))
    // [1, 2, "2", "a", "b", 3, 5, "{}"]

利用sort()排序+递归的方法去重:

function unique (arr) {
     if (!Array.isArray(arr)) return
      arr.sort()
      // 等同于arr.sort((a,b) => {
      //   return a -b
      // })
      let newArr = arr.slice(0)  // newArr跟arr指向不同,相互不影响
      let length = newArr.length
      function loop( index ) {
        if ( index >= 1) {
          if ( newArr[index] === newArr[index -1]){
            newArr.splice( index, 1)
          }
          loop(index -1) // 内部递归调用loop,直到判断条件不满足结束
        }
      }
      loop(length -1) // 调用loop
        return newArr
    }  
   var arr  = [ 1, 2, '2', 'a', 'b', '2', 3, 3,5, 'a', '{}','{}']
    console.log(unique(arr))
    // [1, 2, "2", "a", "b", 3, 5, "{}"]

利用Map数据结构去重(不常用):

function mapArr(arr) {
     if (!Array.isArray(arr)) return
      let map = new Map()
      let newArr = new Array()
      for (let i= 0; i< arr.length; i++ ) {
        if (map.has(arr[i])) {
          map.set(arr[i],true) // 有key值
        } else {
          map.set(arr[i], false) // 没有key值 添加上去
          newArr.push(arr[i])
        }
      }
        return newArr
    }  
   var arr  = [ 1, 2, '2', 'a', 'b', '2', 3, 3,5, 'a', '{}','{}']
    console.log(mapArr(arr))
    // [1, 2, "2", "a", "b", 3, 5, "{}"]

利用reduce()+includes()方法去重(不常用):

 function mapArr(arr) {
     if (!Array.isArray(arr)) return
      return arr.reduce(( prev, index) => prev.includes(index) ? prev : [...prev, index], [])
    }  
   var arr  = [ 1, 2, '2', 'a', 'b', '2', 3, 3,5, 'a', '{}','{}']
    console.log(mapArr(arr))
    // [1, 2, "2", "a", "b", 3, 5, "{}"]

还有一些通过原型链hasOwnPropeeerty()的方法就不一一具体阐述了,后续会继续更新可以实现的maybe,奥利给。。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值