我试图测试[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()
的{{1}}方法进行遏制测试,例如:
Array
而不是关闭。
答案 0 :(得分:8)
有两种不同的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
,则会产生Int
并且等于给定的intValue
。
可能会更频繁地看到第一种方法,但第二种方法 更为通用,例如。
if myArrayOfCustomObjects.contains ({ $0.someProperty == "foo" })
或
if myArrayOfInts.contains ({ $0 > 17 })
所以第一个contains()
是第二个的专门化,用于在equatable元素的数组中进行简单的包含检查。它可以实现为
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?
}