[Any] 和 contains() 的数组

Array of [Any] and contains()

我正在尝试测试 [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

编辑: 我很困惑,因为我看到的所有搜索结果都有 Arraycontains() 方法作为取值进行遏制测试,例如:

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)
})

如果任何数组元素可以转换为 Int,这将产生 true 并且等于给定的 intValue.

他们可能会更频繁地看到第一种方法,但第二种方法 更通用,例如

if myArrayOfCustomObjects.contains ({ [=16=].someProperty == "foo" })

if myArrayOfInts.contains ({ [=17=] > 17 })

所以第一个 contains() 是第二个的一种特殊化,用于对等式元素数组进行简单的包含检查。它可以实现为

extension SequenceType where Generator.Element : Equatable {

    public func contains(element: Self.Generator.Element) -> Bool {
        return self.contains({ [=18=] == 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?
}