Swift [Any]和contains()的数组

Swift [Any]和contains()的数组,swift,enumeration,Swift,Enumeration,我试图测试[Any]类型的数组是否包含特定类型的值(例如,Int) 我知道Swift不知道如何比较Int和任意类型的值,我猜这就是自动完成模板中表达的内容: 包含(谓词:(协议)抛出->Bool) 所以我尝试了以下代码: let intValue:Int = 5 // for example let isContained = myArrayOfAny.contains({ element in return ((element as? Int) == intValue) }) …

我试图测试
[Any]
类型的数组是否包含特定类型的值(例如,
Int

我知道Swift不知道如何比较
Int
和任意类型的值,我猜这就是自动完成模板中表达的内容:

包含(谓词:(协议)抛出->Bool)

所以我尝试了以下代码:

let intValue:Int = 5 // for example

let isContained = myArrayOfAny.contains({ element in 
    return ((element as? Int) == intValue)
})
…并且它可以编译(还不能确保它工作正常);但是仍然不能理解
谓词:(协议)
部分的头绪。这是什么意思?
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

EDIT:我很困惑,因为我看到的所有搜索结果都有
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
}
它要求序列元素符合
相等的

协议,它保证它们可以与
==
进行比较:

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
符合
equalable
, 因此,可以使用此
contains()
方法检查是否存在 指某种元素

这对我来说不起作用

let myArrayOfAny : [Any] = [4, 5, 6]
因为
Any
不符合
equalable
。在这里你可以使用 第二个
包含()
方法

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
}
它接受一个谓词,即布尔函数。而不是 与
==
相比,谓词应用于每个数组元素。 此方法不要求数组元素是
相等的

这就是你在中国所做的

let myArrayOfAny : [Any] = [4, 5, 6]
let intValue:Int = 5 // for example
let isContained = myArrayOfAny.contains({ element in 
    return ((element as? Int) == intValue)
})
如果任何数组元素可以转换为
Int
和等于给定的
intValue

用户可能会更频繁地看到第一种方法,但第二种方法 要普遍得多,例如

if myArrayOfCustomObjects.contains ({ $0.someProperty == "foo" })

因此,第一个
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?
}

您可能需要在数组中循环,对于每个元素,如果将该对象强制转换为Int成功,请进行比较。如果相等,则返回true。否则,继续下一个元素。我知道,straigh forward方法保证有效。不过,这听起来不是很快,谢谢你的回答;非常有启发性。因此,没有简单、不重复的方法来检查定义为
Any
Int
String
Bool
)的变量的值是否包含在
[Any]
类型的数组中,但在运行时保证包含与变量相同类型的值?
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?
}