2016-07-13 12 views
2

Ich möchte eine Erweiterung für Array schreiben, um zu überprüfen, ob ein Array, das alle Elemente eines anderen Array enthält, in meinem Anwendungsfall ist es String-Objekte, aber ich halten get:Überprüfen Sie, ob ein Array alle Elemente eines anderen in Swift enthält

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

in der Linie self.contains(item) den Fehler in etwa item

hier ist mein 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 
    } 
} 

Antwort

8

Sie benötigt haben, dass die Sequenzelemente 0 sind, , aber sie haben nichts mit den Array-Elementen zu tun. Daher

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

kompiliert nicht.

Was Sie wahrscheinlich wollen, ist zu verlangen, dass die Sequenzelemente, die die gleichen Typ wie die Array-Elemente haben (und das sollte Equatable sein):

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

Wenn Sie die Methode für die Array-Argumente nur brauchen, und nicht für allgemeine Sequenzen dann können Sie die Erklärung zu

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

vereinfachen, die

verkürzt werden kann

Wie @AMomchilov sagte hat eine lineare Suche, so dass diese hat O(M*N) Komplexität wo M und N die Länge den beiden Anordnungen sind. Sie könnten eine Spezialisierung für den Fall definieren , dass die Elemente Hashable sind, und tun, um die Mitgliedschaft Scheck gegen ein Set:

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

Ob dies schneller als die vorherige Methode oder nicht auf beiden Feldgrößen abhängen würden und auch auf dem Elementtyp (wie "teuer" ist es Elemente zu vergleichen).

+0

Hinweis zu OP: Dies kann viel beschleunigt werden, wenn ein Set verwendet wird. '.contains' führt eine langsame lineare Suche durch. Diese Lösung hat insgesamt eine quadratische Zeitkomplexität. – Alexander

+1

@AMomchilov: Ja (wenn die Elemente 'Hashable' sind). –

+0

@AMomchilov also was schlägst du vor? – iOSGeek

Verwandte Themen