我正在尝试测试类型数组是否[Any]
包含特定类型的值(比方说Int
).
我知道Swift不知道如何比较一个Int
和任意类型的值,我想这就是在自动完成模板中表达的内容:
contains(predicate: (protocol<>) throws -> Bool)
所以我尝试了这段代码:
let intValue:Int = 5 // for example let isContained = myArrayOfAny.contains({ element in return ((element as? Int) == intValue) })
......它编译(无法确定它是否有效); 但仍然无法做出部分的正面或反面predicate: (protocol<>)
.这是什么意思?文档SequenceType
是非常神秘的:
contains(_: (Self.Generator.Element) throws -> Bool) rethrows -> Bool Default Implementation Return true iff an element in self satisfies predicate. Declaration @warn_unused_result func contains(@noescape _ predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Bool
编辑:我很困惑,因为我所见过的所有搜索结果都只是采用了测试包含值的contains()
方法Array
,例如:
if myArrayOfInt.contains(someInt){ ...
而不是封闭.
有两种不同的contains()
方法(两种协议扩展SequenceType
).第一个是
extension SequenceType where Generator.Element : Equatable { /// Return `true` iff `element` is in `self`. @warn_unused_result public func contains(element: Self.Generator.Element) -> Bool }
并且它要求序列元素符合Equatable
协议,这保证了它们可以与==
以下内容进行比较:
public protocol Equatable { // ... public func ==(lhs: Self, rhs: Self) -> Bool }
例如,在
let intValue:Int = 5 let myArrayOfInt = [4, 5, 6] let isContained = myArrayOfInt.contains(intValue)
你有一个数组Int
,并且Int
符合Equatable
,所以这个contains()
方法可以用来检查某个元素的存在.
这不起作用
let myArrayOfAny : [Any] = [4, 5, 6]
因为Any
不符合Equatable
.在这里你可以使用第二种contains()
方法
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 }
它采用谓词,即布尔函数.而不是与之比较==
,谓词应用于每个数组元素.此方法不要求数组元素Equatable
.
这就是你所做的
let myArrayOfAny : [Any] = [4, 5, 6] let intValue:Int = 5 // for example let isContained = myArrayOfAny.contains({ element in return ((element as? Int) == intValue) })
true
如果任何数组元素可以强制转换为a Int
并且等于给定的数组元素,则会产生这种情况intValue
.
可能会更频繁地看到第一种方法,但第二种方法更为通用,例如
if myArrayOfCustomObjects.contains ({ $0.someProperty == "foo" })
要么
if myArrayOfInts.contains ({ $0 > 17 })
所以第一个contains()
是第二个的特化,用于在等可元素的数组中进行简单的包含检查.它可以实现为
extension SequenceType where Generator.Element : Equatable { public func contains(element: Self.Generator.Element) -> Bool { return self.contains({ $0 == element } ) } }
你会发现indexOf()
它有两种风格:
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? }