检查数组是否包含Swift中另一个的所有元素

iOS*_*eek 2 arrays generics ios swift swift2

我想为数组编写一个扩展来检查一个数组是否包含另一个数组的所有元素,在我的用例中它是字符串对象,但我一直得到:

Cannot convert value of type 'T.Generator.Element' to expected argument type '@noescape _ throws -> Bool'
Run Code Online (Sandbox Code Playgroud)

在行中self.contains(item)的错误约item

这是我的代码:

extension Array {
    func containsArray<T : SequenceType where T.Generator.Element : Equatable> (array:T) -> Bool{
        for item:T.Generator.Element in array{
            if !self.contains(item) {
                return false
            }
        }
        return true
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 8

您需要序列元素Equatable,但它们与数组元素无关.因此

 if !self.contains(item) { ... }
Run Code Online (Sandbox Code Playgroud)

不编译.

你可能想要的是要求序列元素与数组元素具有相同的类型(应该是Equatable):

extension Array where Element: Equatable {
    func containsArray<T : SequenceType where T.Generator.Element == Element> (array:T) -> Bool {
        for item in array {
            if !self.contains(item) {
                return false
            }
        }
        return true
    }
}
Run Code Online (Sandbox Code Playgroud)

如果只需要数组参数的方法而不需要通用序列,则可以将声明简化为

extension Array where Element: Equatable {
    func containsArray(array: [Element]) -> Bool {
        for item in array {
            if !self.contains(item) {
                return false
            }
        }
        return true
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以缩短为

extension Array where Element: Equatable {
    func containsArray(array: [Element]) -> Bool {
        return !array.contains { !self.contains($0) }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如@AMomchilov所说,contains()进行线性搜索,因此这具有O(M*N)复杂性,M并且N是两个数组的长度.您可以为元素的大小写定义一个特化,并对以下内容进行Hashable成员资格检查Set:

extension Array where Element: Hashable {
    func containsArray(array: [Element]) -> Bool {
        let selfSet = Set(self)
        return !array.contains { !selfSet.contains($0) }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是否比以前的方法更快将取决于数组大小以及元素类型(比较元素的"昂贵").