最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 数组去重的十一种方式

    正文概述 掘金(bghunter)   2021-02-09   515

    数组中数据全部为基本数据类型

    1、Set方法配合展开运算符实现

    原数组不会被改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique(arr) {
      if (!arr || arr.length === 0) return []
      return [...new Set(arr)]
    }
    console.log(unique(data)) // [1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]
    

    思路:利用Set方法不能含有相同值的特性,返回时利用展开运算符(...)返回一个新的数组,因此原数组不会被改变。

    2、Set方法配合Array.from方法实现

    原数组不会被改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique(arr) {
      if (!arr || arr.length === 0) return []
      return Array.from(new Set(arr))
    }
    console.log(unique(data)) // [1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]
    

    思路:利用Array.from方法,该方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。因此原数组不会被改变。

    3、for循环配合数组indexOf方法实现

    原数组不会被改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique(arr) {
      if (!arr || arr.length === 0) return []
      let ary = []
      for(let i = 0, length = arr.length; i < length; i++) {
        if (ary.indexOf(arr[i]) === -1) {
          ary.push(arr[i])
        }
      }
      return ary
    }
    console.log(unique(data)) // [1, 3, 4, "4", 5, "7", undefined, 7, NaN, NaN, null]
    

    思路:利用一层for循环遍历,在for循环的代码块中再使用数组的indexOf方法,来判断新声明的数组中是否存在当前项的索引, 从而达到去重的效果,由于是新声明的数组来存放去重后的数据,因此原数组不会被改变。

    4、for循环配合数组includes方法实现

    原数组不会被改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique(arr) {
      if (!arr || arr.length === 0) return []
      let ary = []
      for(let i = 0, length = arr.length; i < length; i++) {
        if (!ary.includes(arr[i])) {
          ary.push(arr[i])
        }
      }
      return ary
    }
    console.log(unique(data)) // [1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]
    

    思路:这种实现方式与上面的indexOf方法实现的一样,原数组也不会被改变。

    5、利用Map方法实现

    原数组不会被改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique(arr) {
      if (!arr || arr.length === 0) return []
      let map = new Map()
      let ary = []
      for(let i = 0, len = arr.length; i < len; i++) {
        if (map.has(arr[i])) {
          map.set(arr[i], true)
        } else {
          map.set(arr[i], false)
          ary.push(arr[i])
        }
      }
      return ary
    }
    console.log(unique(data)) // [1, 3, 4, "4", 5, "7", undefined, 7, NaN, null] 
    

    思路:利用一层for循环遍历,在for循环的代码块中再使用Map的hasset方法,来判断新声明的数组中是否存在当前项,存在的话将其value设置为true,反之设置为false并使用额外声明的数组变量保存起来,由于是新声明的数组来存放去重后的数据,因此原数组不会被改变。

    6、利用Map方法配合数组的filter方法实现

    原数组不会被改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique(arr) {
      if (!arr || arr.length === 0) return []
      let map = new Map()
      return arr.filter(item => !map.has(item) && map.set(item, 1))
    }
    console.log(unique(data)) // [1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]
    

    思路:利用数组的filter方法的特性,该方法会返回一个新的数组,因此原数组不会被改变。

    7、利用reduce方法实现

    原数组不会被改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique(arr) {
      if (!arr || arr.length === 0) return []
      let ary = arr.reduce((accumulator, current) => {
        return accumulator.includes(current) ? accumulator : accumulator.concat(current)
      }, [])
      return ary
    }
    console.log(unique(data)) // [1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]
    

    思路:利用数组的reduce方法实现,上面这种实现方式原数组不会被改变。其实reduce方法很强大,可以做很多事情,例如:数组去重、数组降维(拍平)、数组求和等等,这里就不赘述了。

    8、利用对象键值对

    原数组不会改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique(arr) {
      if (!arr || arr.length === 0) return []
      let map = {}
      let ary = []
      for(let i = 0, len = arr.length; i < len; i++) {
        if (map[arr[i]]) continue
        ary.push(arr[i])
        map[arr[i]] = true
      }
      return ary
    }
    console.log(unique(data)) //  [1, 3, 4, 5, "7", undefined, NaN, null] 
    

    思路:利用for循环,将遍历的子项存放到map对象中,不存在就放到新数组中,这种方式原数组也不会被改变。缺点就是如果string和number类型的值时相等的,那么也会被过滤掉,这种方式限制比较大。

    9、双层for循环方法实现(一)

    原数组会被改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique(arr) {
      if (!arr || arr.length === 0) return []
      for(let i = 0, len = arr.length; i < len; i++) {
        for(let j = i + 1, len = arr.length; j < len; j++) {
          if (arr[i] === arr[j]) {
            arr.splice(j, 1)
            j--
            len--
          }
        }
      }
      return arr
    }
    console.log(unique(data)) // [1, 3, 4, "4", 5, "7", undefined, 7, NaN, NaN, null]
    

    思路:使用双重for循环,外层循环控制次数,内层循环将j变量赋值为i + 1, 在循环体中判断外层循环的索引项与内层循环的索引项是否相等,如果相等 利用splice方法将当前项删除,同时将j和arr数组的长度同时减一,如此往复从而实现去重,由于是直接操作传进来的参数,并将该参数返回出去, 因此原数组会被改变。

    10、双层for循环方法实现(二)

    原数组不会改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique(arr) {
      let ary = []
      if (!arr || arr.length === 0) return []
      for(var i = 0, len = arr.length; i < len; i++) {
        for(var j = 0, aryLen = ary.length; j < aryLen; j++) {
          if (arr[i] === ary[j]) break
        }
        if (j === aryLen) {
          ary.push(arr[i])
        }
      }
      return ary
    }
    console.log(unique(data)) // [1, 3, 4, "4", 5, "7", undefined, 7, NaN, NaN, null]
    

    思路:两层for循环,外层循环遍历的是入参数组,内层循环遍历的是新声明的ary数组,在内层循环体中判断,两个数组中对应的索引值是否相等,相等跳出循环,外层循环体中判断变量jary数组的长度是否相等, 由于是新声明的数组来存放去重后的数据,因此原数组不会被改变。

    11、使用sort方法排序后去重

    原数组不会改变

    const data = [1,3,4,"4",5,"4","7",undefined,7,7, NaN, undefined, NaN, null, null]
    function unique (arr) {
      if (!arr || arr.length === 0) return []
      let ary = arr.sort()
      let flag;
      let result = []
      for(let i = 0, len = ary.length; i < len; i++) {
        // 判断是否为第一个元素或者相邻的元素不相同
        if (!i || flag !== ary[i]) {
          result.push(ary[i])
        }
        flag = ary[i]
      }
      return result
    }
    console.log(unique(data)) // [1, 3, 4, "4", 5, "7", 7, NaN, NaN, null, undefined]
    

    思路:先利用排序方法排序后,再判断相邻两个元素是否相同的思路,一层for循环控制遍历次数,循环体中判断是否为第一个元素或者相邻的元素不相同,条件为真时将数据放入新声明的数组中。由于是新声明的数组来存放去重后的数据,因此原数组不会被改变。

    总结

    这些方法都是针对一维数组且数组不为对象数组的方法,下面为了方便对比,直接将几种方法进行了对比,这些实现方式最后的结果会有差别,但这不是最重要的,重要的是我们要知道什么场景使用什么方式去解决才好。

    方法序号打印结果说明
    1[1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]对NaN可以去重2[1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]对NaN可以去重3[1, 3, 4, "4", 5, "7", undefined, 7, NaN, NaN, null]对NaN不能去重4[1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]对NaN可以去重5[1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]对NaN可以去重6[1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]对NaN可以去重7[1, 3, 4, "4", 5, "7", undefined, 7, NaN, null]对NaN可以去重8[1, 3, 4, 5, "7", undefined, NaN, null]对NaN可以去重,值相同的string和number根据先后顺序会被去重9[1, 3, 4, "4", 5, "7", undefined, 7, NaN, NaN, null]对NaN不能去重10[1, 3, 4, "4", 5, "7", undefined, 7, NaN, NaN, null]对NaN不能去重11[1, 3, 4, "4", 5, "7", 7, NaN, NaN, null, undefined]对NaN不能去重

    参考文章

    github.com/mqyqingfeng…

    www.cnblogs.com/echolun/p/1…


    起源地下载网 » 数组去重的十一种方式

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元