Swift中使用Contains的正確姿勢

搶手的哥發表於2018-03-05

1.正確姿勢

當我們在用Swift進行編碼的時候,經常會用到contains(element:)方法來判斷Array是否包含了某個元素。舉個栗子:

enum Animal {
  case dog
  case cat
}
let animals: [Animal] = [.dog, .dog]
let hasCat = animals.contains(.cat)       // fasle
複製程式碼

看起來灰常的簡單對不?然鵝,我們把Animal的列舉定義修改成帶引數的列舉,比如這樣:

enum Animal {
  case dog(String)
  case cat(String)
}
let animals: [Animal] = [.dog("汪汪"), .dog("阿黃")]
let hasCat = animals.contains(.cat("喵喵"))      // compile error  
複製程式碼

編譯報錯了,為毛? 原因是能使用contains(element:)的元素是需要遵循Equatable協議的,但是Animal是沒有遵循的,所以會報錯。

那腫麼辦?幸好蘋果還提供了另外一個方法來判斷

public func contains(where predicate: (Element) throws -> Bool)
rethrows -> Bool
複製程式碼

這個方法提供了一個閉包引數—— predicate,當陣列中的元素沒有遵循Equatable協議時,我們可以用這個引數來定義檢查元素的規則。

所以之前程式碼中的錯誤程式碼改成這樣:

enum Animal {
    case dog(String)
    case cat(String)
}

let animals : [Animal] = [.dog("汪汪"), .dog("阿黃")]
let hasCat = animals.contains { (animal) -> Bool in
    
    if case .cat = animal {
        return true
    }
    
    return false
}

// fasle
複製程式碼

這麼改hasCat就能正確計算出是false了。

2.進階用法

另外,我們可以自定義predicate,來定義檢查篩選的條件,比如: 檢查陣列中是否有元素大於100。

let expenses = [21.37, 55.21, 9.32, 10.18, 388.77, 11.41]
let hasBigPurchase = expenses.contains { $0 > 100 }
// 'hasBigPurchase' == true
複製程式碼

再給個栗子:檢查一個陣列的元素,它可是否以除以7。

let array = [2, 5, 6, 7, 19, 40]

array.contains { (element) -> Bool in
    element % 7 == 0
}
或者
array.contains { $0 % 7 == 0 } 
複製程式碼

這裡的$0就是指陣列的元素;

原文連結: Contains in Swift -- by 故胤道長(英文部落格,需要科學上網工具) 官方文件

相關文章