问题
I want to write an extension for array to check if an array contains all the elements of another array, in my use case it's string objects but I keep get:
Cannot convert value of type 'T.Generator.Element' to expected argument type '@noescape _ throws -> Bool'
in the line self.contains(item)
the error in about item
here is my code:
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:
You have required that the sequence elements are Equatable
,
but they are unrelated to the array elements. Therefore
if !self.contains(item) { ... }
does not compile.
What you probably want is to require that the sequence elements have the
same type as the array elements (and that should be 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
}
}
If you need the method for array arguments only and not for general sequences then you can simplify the declaration to
extension Array where Element: Equatable {
func containsArray(array: [Element]) -> Bool {
for item in array {
if !self.contains(item) {
return false
}
}
return true
}
}
which can be shortened to
extension Array where Element: Equatable {
func containsArray(array: [Element]) -> Bool {
return !array.contains { !self.contains($0) }
}
}
As @AMomchilov said, contains()
does a linear search, so this
has O(M*N)
complexity where M
and N
are the length of
the two arrays. You could define a specialization for the case
that the elements are Hashable
, and do the membership check
against a Set
:
extension Array where Element: Hashable {
func containsArray(array: [Element]) -> Bool {
let selfSet = Set(self)
return !array.contains { !selfSet.contains($0) }
}
}
Whether this is faster than the previous method or not would depend on both array sizes and also on the element type (how "expensive" is it to compare elements).
来源:https://stackoverflow.com/questions/38361574/check-if-an-array-contains-all-elements-of-another-in-swift