js 數組深度去重

  在平常開發中不免會遇到數組去重的難題,最近,正是給一個數組去重的難題難到了。做爲開發者的咱們,一旦遇到問題必然就是谷歌,百度,MDN....搜索一波,可是,這些地方都沒有找到我想要的答案。或許看到這你會開噴了,咋沒有啊,網上一大堆去重方法,可是,這裏的需求要的是深度去重,也就是說,引用類型也要去掉!!這時你會發現不少方法都無論用了,看了一波度孃的答案,絕大部分的都是循環,索引相等的方法去重,並且舉的例子都是基本數據類型的去重,若是手上拿的是一個全是引用類型的數組,你會發現這些方法都沒用了。在講正題以前,先講一個基本數據類型去重的方法:git

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

注意:該方法也只能用在全是基本類型的數組上,一旦有重複的引用類型的數據就沒法過濾了。github

  回到正題上,怎麼給引用類型的數組去重,先定義下面一個方法:數組

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

該方法用於區分對象和數組,若是是對象,則返回的是 Object ,若是是數組,則返回 Array。spa

定義方法,用於檢查兩個對象裏面的內容是否一致,若一致,返回 true ,不然返回 false:prototype

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:code

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]
}

這裏,再強調一次,若是數組元素沒有順序要求,或者數組中全部元素都是同一類型(都是對象或都是數組),纔可以使用。另外,若是還有更好的方法歡迎補充,謝謝。blog

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

相關文章
相關標籤/搜索