zoukankan      html  css  js  c++  java
  • js 数组深度去重

      在日常开发中难免会遇到数组去重的难题,最近,正是给一个数组去重的难题难到了。作为开发者的我们,一旦遇到问题必然就是谷歌,百度,MDN....搜索一波,但是,这些地方都没有找到我想要的答案。或许看到这你会开喷了,咋没有啊,网上一大堆去重方法,但是,这里的需求要的是深度去重,也就是说,引用类型也要去掉!!这时你会发现很多方法都不管用了,看了一波度娘的答案,绝大部分的都是循环,索引相等的方法去重,而且举的例子都是基本数据类型的去重,如果手上拿的是一个全是引用类型的数组,你会发现这些方法都没用了。在讲正题之前,先讲一个基本数据类型去重的方法:

    arr = Array.from(new Set(arr))

    注意:该方法也只能用在全是基本类型的数组上,一旦有重复的引用类型的数据就无法过滤了。

      回到正题上,怎么给引用类型的数组去重,先定义下面一个方法:

    function getType(target) {
         return Object.prototype.toString.call(target).slice(8,-1)
    }

    该方法用于区分对象和数组,如果是对象,则返回的是 Object ,如果是数组,则返回 Array。

    定义方法,用于检查两个对象里面的内容是否一致,若一致,返回 true ,否则返回 false:

    function objUnique(a,b) {
         if(getType(a) !== 'Object' && getType(b) !== 'Object'){
             return false
         }
         let testList = Object.keys(a)
         for(let i = 0;i < testList.length;i++){
             let propName = testList[i]
             if(getType(a[propName]) === 'Object' && getType(b[propName]) === 'Object'){
                 objUnique(a[propName],b[propName])
             }else if(getType(a[propName]) === 'Array' && getType(b[propName]) === 'Array'){
                 arrUnique(a[propName],b[propName])
             }else if(a[propName] !== b[propName]){
                 return false
             }
         }
         return true
    }

    定义方法,用于检测两个数组的内容是否一致,若一致返回 true,否则返回 false:

    function arrUnique(a, b) {
        if(getType(a) !== 'Array' && getType(b) !== 'Array'){
           return false
        }
        if(a.length !== b.length){
           return false
        }
        for(let i = 0;i < a.length;i++){
           if(getType(a[i]) === 'Object' && getType(b[i]) === 'Object'){
                objUnique(a[i],b[i])
           }else if(getType(a[i]) === 'Array' && getType(b[i]) === 'Array'){
                arrUnique(a[i],b[i])
           }else if(a[i] !== b[i]){
                return false
           }
        }
        return true
    }

    最后,讲目标数组所有元素进行分类(当然,这里忽略了元素的顺序,如果数组元素没有顺序要求,或者数组的元素全是同一种类型的情况,则可以正常使用,否则另寻办法),分别将基本类型,对象,数组放入一个容器中,然后用上面的三个方法分别对里面的所有元素进行去重,再将三个数组重新组合:

    function unique(arr) {
        if(getType(arr) !== 'Array'){
            return null
        }
        // 基本数据类型容器
        let commonList = []
        // 对象收纳容器
        let objList = []
        // 数组收纳容器
        let arrList = []
    
        // 数据分类
        arr.forEach(item => {
            if(getType(item) === 'Object'){
                objList.push(item)
            }else if(getType(item) === 'Array'){
                arrList.push(item)
            }else{
                commonList.push(item)
            }
        })
        // 基本数据类型去重
        commonList = Array.from(new Set(commonList))
        // 对象收纳容器去重
        for(let i = 0;i < objList.length;i++){
            for(let j = i + 1;j < objList.length;j++){
                if(objUnique(objList[i],objList[j])){
                    objList.splice(j,1)
                    j--
                }
            }
        }
        // 数组收纳容器去重
        for(let i = 0;i < arrList.length;i++){
            for(let j = i + 1;j < arrList.length;j++){
                if(arrUnique(arrList[i],arrList[j])){
                    arrList.splice(j,1)
                    j--
                }
            }
        }
        // 合并收纳容器
        return [...commonList,...objList,...arrList]
    }

    这里,再强调一次,如果数组元素没有顺序要求,或者数组中所有元素都是同一类型(都是对象或都是数组),才可使用。另外,如果还有更好的方法欢迎补充,谢谢。

    github地址:https://github.com/JonasVon/unique.git

  • 相关阅读:
    POJ 3114 Tarjan+Dijkstra
    278. First Bad Version
    209. Minimum Size Subarray Sum
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    710. Random Pick with Blacklist
    767. Reorganize String
    524. Longest Word in Dictionary through Deleting
    349. Intersection of Two Arrays
    350. Intersection of Two Arrays II
  • 原文地址:https://www.cnblogs.com/jonas-von/p/9595444.html
Copyright © 2011-2022 走看看