Вы необходимо, чтобы элементы последовательности равны 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, делает линейный поиск, так что это имеет 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) }
}
}
ли это быстрее, чем предыдущий метод или нет, будет зависеть от обоих размеров массива и также по типу элемента (как «дорого» это сравнить элементы).
Примечание к OP: это может быть очень много ускорено, если используется набор. '.contains' выполняет медленный линейный поиск. Это решение в целом имеет квадратичную временную сложность. – Alexander
@AMomchilov: Да (если элементы 'Hashable'). –
@AMomchilov, так что вы предлагаете? – iOSGeek