我想为数组编写一个扩展名,以检查一个数组是否包含另一个数组的所有元素,在我的用例中,它是字符串对象,但我一直得到:
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
}
}
您已要求sequence元素为Equatable
,但它们与数组元素无关。所以
if !self.contains(item) { ... }
不编译。
您可能想要的是要求sequence元素具有与array元素相同的类型(应该为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)
复杂,其中M
和N
是两个数组的长度。您可以针对元素为的情况定义特殊化Hashable
,并针对进行成员资格检查Set
:
extension Array where Element: Hashable {
func containsArray(array: [Element]) -> Bool {
let selfSet = Set(self)
return !array.contains { !selfSet.contains($0) }
}
}
这是否比以前的方法快,将取决于数组的大小以及元素的类型(比较元素的“昂贵程度”)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句