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

时间:2016-07-13 20:57:55

标签: ios arrays swift generics swift2

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

Cannot convert value of type 'T.Generator.Element' to expected argument type '@noescape _ throws -> Bool'

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

1 个答案:

答案 0 :(得分:8)

您要求序列元素为Equatable, 但它们与数组元素无关。因此

 if !self.contains(item) { ... }

无法编译。

你可能想要的是要求序列元素具有 与数组元素相同的类型(应该是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
    }
}

如果只需要数组参数的方法,而不是 一般序列然后你可以简化声明

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

可以缩短为

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

正如@AMomchilov所说,contains()进行线性搜索,所以这个 复杂度为O(M*N)MN的长度为Hashable 这两个数组。您可以为案例定义专业化 元素为Set,并进行成员资格检查 针对extension Array where Element: Hashable { func containsArray(array: [Element]) -> Bool { let selfSet = Set(self) return !array.contains { !selfSet.contains($0) } } }

$(dir5)\include;

这是否比以前的方法更快将取决于两者 数组大小以及元素类型(如何“昂贵”) 是比较元素。)