There are two different contains()
methods (both protocol
extensions to SequenceType
). The first one is
extension SequenceType where Generator.Element : Equatable {
/// Return `true` iff `element` is in `self`.
@warn_unused_result
public func contains(element: Self.Generator.Element) -> Bool
}
and it requires that the sequence elements conform to the Equatable
protocol, which guarantees that they can be compared with ==
:
public protocol Equatable {
// ...
public func ==(lhs: Self, rhs: Self) -> Bool
}
For example, in
let intValue:Int = 5
let myArrayOfInt = [4, 5, 6]
let isContained = myArrayOfInt.contains(intValue)
you have an array of Int
, and Int
conforms to Equatable
,
so this contains()
method can be used to check for the presence
of a certain element.
This does not work for
let myArrayOfAny : [Any] = [4, 5, 6]
because Any
does not conform to Equatable
. Here you can use
the second contains()
method
extension SequenceType {
/// Return `true` iff an element in `self` satisfies `predicate`.
@warn_unused_result
public func contains(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Bool
}
which takes a predicate, i.e. a boolean function. Instead of
comparing with ==
, the predicate is applied to each array element.
This method does not require that the array elements are Equatable
.
And that's what you do in
let myArrayOfAny : [Any] = [4, 5, 6]
let intValue:Int = 5 // for example
let isContained = myArrayOfAny.contains({ element in
return ((element as? Int) == intValue)
})
This will yield true
if any array element can be cast to an Int
and is equal to the given intValue
.
The might see the first method more frequently but the second
is far more general, e.g.
if myArrayOfCustomObjects.contains ({ $0.someProperty == "foo" })
or
if myArrayOfInts.contains ({ $0 > 17 })
So the first contains()
is a kind of specialization of the second one for a simple containment check in arrays of equatable elements. It could be implemented as
extension SequenceType where Generator.Element : Equatable {
public func contains(element: Self.Generator.Element) -> Bool {
return self.contains({ $0 == element } )
}
}
You'll find the same with indexOf()
which also comes in
two flavors:
extension CollectionType where Generator.Element : Equatable {
// ...
public func indexOf(element: Self.Generator.Element) -> Self.Index?
}
extension CollectionType {
// ...
public func indexOf(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Index?
}