Contains in Swift
While coding Swift, we use contains(element:)
to determine if an array contains the element or not. For example:
enum Animal {
case dog
case cat
}let animals: [Animal] = [.dog, .dog]
let hasCat = animals.contains(.cat) // false
Looks pretty simple, right? However, let us change Animal enum’s definition with associated values like this:
enum Animal {
case dog(String)
case cat(String)
}let animals: [Animal] = [.dog("Growlithe"), .dog("Rockruff")]
let hasCat = animals.contains(.cat("Meowth")) // compile error
Boo, compile error! This is due to the element used in contains(element:)
function should conform to Equatable
protocol, while Animal enum with associated value does not.
Fortunately, we have another contains function defined as below:
public func contains(where predicate: (Element) throws -> Bool) rethrows -> Bool
This function takes a closure as a parameter — the predicate. We could use it to define how to check an element of a type that doesn’t conform to the Equatable
protocol.
Based on this contains function, let us fix the compile error above:
enum Animal { case dog(String) case cat(String)}
let animals: [Animal] = [.dog("Growlithe"), .dog("Rockruff")]let hasCat = animals.contains { animal in if case .cat = animal { return true } return false}
Now hasCat would return false. Alternatively, a predicate can be satisfied by a range of Equatable
elements or a general condition. This example shows how you can check an array for an element could be divided by 7.
let array = [2, 5, 6, 7, 19, 40]
array.contains { (element) -> Bool in
element % 7 == 0
}
Apple’s API page also offers a very good example in handling network response with contains(where:) function.
If you have a better use case, please share it in the comments below!