Swift泛型應(yīng)用:模型數(shù)組去重

我們?cè)赟wift開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)碰到數(shù)組去重的情況,基本數(shù)據(jù)類(lèi)型數(shù)組的去重比較好辦,那如果碰到model模型類(lèi)的數(shù)組去重,又怎么進(jìn)行科學(xué)合理的處理呢?通常對(duì)model進(jìn)行去重,要依賴其某個(gè)屬性,一般是一個(gè)唯一ID,然后通過(guò)該ID來(lái)進(jìn)行判斷是否有重復(fù)的模型。
比如有個(gè)模型AModel如下:

class AModel {
    
    var name: String?
    var img: String?
    var aID: Int = 0 //唯一ID
 
}

普通處理

AModel的屬性中有可以用來(lái)判斷唯一性的aID,因此我們?cè)趯?duì)裝著AModel類(lèi)型的數(shù)組[AModel]進(jìn)行去重時(shí)可以這么處理:

func handleFilterArray(arr:[AModel]) -> [AModel] {
        var temp = [AModel]()  //存放符合條件的model
        var idxArr = [Int]()   //存放符合條件model的aID,用來(lái)判斷是否重復(fù)
        for model in arr {
            let index = model.aID   //遍歷獲得model的唯一標(biāo)識(shí)aID
            if !idxArr.contains(index){    //如果該aID已經(jīng)添加過(guò),則不再添加
                idxArr.append(index)    
                temp.append(model)    //如果該aID沒(méi)有添加過(guò),則添加到temp數(shù)組中
            }
        }
        return temp    //最終返回的數(shù)組中已經(jīng)篩選掉重復(fù)aID的model
    }

泛型處理

如果我們需要處理不同model類(lèi)型的數(shù)組,那我們是否可以將上面的方法寫(xiě)成一個(gè)通用的方法,比如下面這樣用Swift的泛型來(lái)處理:

//T為不同model的類(lèi)型
func handleFilterArray(arr:[T]) -> [T] {
     //具體實(shí)現(xiàn)
}

可是我們碰到一個(gè)問(wèn)題,你用泛型來(lái)寫(xiě)的話,這個(gè)泛型無(wú)法確定你不同模型中需要判斷的那個(gè)ID是什么,因?yàn)锽Model的唯一ID是bID,CModel的唯一ID是cID,因此我們?cè)趺床拍馨堰@個(gè)不同的標(biāo)識(shí)符給帶到這個(gè)函數(shù)中來(lái)呢,下面先來(lái)看方法一,利用protocol來(lái)處理:

protocol arrayFilterable {
    var identifer:Int {get}  //該只讀屬性用來(lái)獲取不同model的不同唯一ID
}

extension AModel: arrayFilterable{
    var identifer: Int{
        return aID  //AModel則返回aID
    }
}

extension BModel: arrayFilterable{
    var identifer: Int{
        return bID  //BModel則返回bID
    }
}

然后我們的處理方法就可以寫(xiě)成這樣:

func handleFilterArray<T:arrayFilterable>(arr:[T]) -> [T] {
        var temp = [T]()
        var idxArr = [Int]()
        for model in arr {
            let index = model.identifer  //通過(guò)identifer來(lái)判斷不同模型是否有重復(fù)數(shù)據(jù)
            if !idxArr.contains(index){
                idxArr.append(index)
                temp.append(model)
            }
        }
        return temp
    }

更合理的泛型處理

但以上的方法是不是還是顯得有點(diǎn)不那么高效,畢竟需要每個(gè)模型都遵循arrayFilterable協(xié)議,而且顯得可擴(kuò)展性一般,如果有一個(gè)DModel用來(lái)判斷唯一性的不是ID,而是一個(gè)字符串呢,我們?cè)賮?lái)看看方法二,利用泛型結(jié)合Swift數(shù)組的高階函數(shù)map來(lái)處理:

//直接給Array擴(kuò)展一個(gè)方法
extension Array {

  //該函數(shù)的參數(shù)filterCall是一個(gè)帶返回值的閉包,傳入模型T,返回一個(gè)E類(lèi)型
   func handleFilter<E: Equatable>(_ filterCall: (T) -> E) -> [T] {
      var temp = [T]()
      for model in self {
          //調(diào)用filterCall,獲得需要用來(lái)判斷的屬性E
          let identifer = filterCall(model)  
          //此處利用map函數(shù) 來(lái)將model類(lèi)型數(shù)組轉(zhuǎn)換成E類(lèi)型的數(shù)組,以此來(lái)判斷
          identifer 是否已經(jīng)存在,如不存在則將model添加進(jìn)temp
          if !temp.map( { filterCall($0) } ).contains(identifer) {
              temp.append(model)
          }
      }
      return temp
   }
}

上面?zhèn)魅腴]包filterCall的返回值E,就是模型的屬性中用來(lái)判斷唯一型的那個(gè)屬性,需要遵循Equatable,才能使用數(shù)組的contains函數(shù)來(lái)判斷是否已經(jīng)存在。

如果AModel用來(lái)判斷唯一性的不是aID,而是name屬性,則一個(gè)裝著有好多重復(fù)AModel的數(shù)組AModelArray可以這么調(diào)用這個(gè)函數(shù):

let filterArray = AModelArray.handleFilter( { $0.name } )

$0.name即filterCall閉包的返回值,用來(lái)判斷數(shù)組中model唯一性的依據(jù)。

結(jié)語(yǔ)

通過(guò)這個(gè)小應(yīng)用,可以看出Swift中強(qiáng)大的泛型特性能夠讓我們根據(jù)不同的需求,來(lái)編寫(xiě)靈活強(qiáng)大的函數(shù)和類(lèi)型,讓我們避免重復(fù)冗余的代碼,更加快速高效的達(dá)到應(yīng)用目的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,026評(píng)論 4 61
  • 本章將會(huì)介紹 泛型所解決的問(wèn)題泛型函數(shù)類(lèi)型參數(shù)命名類(lèi)型參數(shù)泛型類(lèi)型擴(kuò)展一個(gè)泛型類(lèi)型類(lèi)型約束關(guān)聯(lián)類(lèi)型泛型 Where...
    寒橋閱讀 712評(píng)論 0 2
  • 我大二了,英文專(zhuān)業(yè)。很多時(shí)候我都在想如果我當(dāng)時(shí)進(jìn)了中文系,會(huì)不會(huì)是現(xiàn)在這個(gè)尷尬的樣子,英文不想學(xué),中文沒(méi)空學(xué)。...
    時(shí)光簡(jiǎn)成煙閱讀 337評(píng)論 0 0
  • 今天體重沒(méi)掉,有點(diǎn)小傷心……不過(guò)感覺(jué)體脂應(yīng)該是低了,腹肌快長(zhǎng)全了…… 附贈(zèng)今天早上鍛煉完后拍的局部照(燈光還是一樣...
    健康起飛吧閱讀 422評(píng)論 0 0

友情鏈接更多精彩內(nèi)容