检查一个数组是否包含Swift中另一个元素的所有元素
我想写一个数组的扩展来检查一个数组是否包含另一个数组的所有元素,在我的使用情况下它是string对象,但我一直得到:
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 } }
您已经要求序列元素是可Equatable
,但它们与数组元素无关。 因此
if !self.contains(item) { ... }
不编译。
你可能想要的是要求序列元素具有与数组元素相同的types(并且应该是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()
做一个线性search,所以这有O(M*N)
复杂性,其中M
和N
是两个数组的长度。 你可以为元素是Hashable
的情况定义一个专门Hashable
,并且对一个Set
进行成员资格检查:
extension Array where Element: Hashable { func containsArray(array: [Element]) -> Bool { let selfSet = Set(self) return !array.contains { !selfSet.contains($0) } } }
这是否比以前的方法更快取决于数组大小和元素types(比较元素的“昂贵”)。