2016-12-15 4 views
0

Ich versuche, die unter Swift 2 Erweiterungsmethode Swift 3.‚Generator‘ ist kein Mitglied Art von ‚Self.SubSequence‘

extension CollectionType { 

    func chunk(withDistance distance: Index.Distance) -> [[SubSequence.Generator.Element]] { 
     var index = startIndex 
     let generator: AnyGenerator<Array<SubSequence.Generator.Element>> = anyGenerator { 
      defer { index = index.advancedBy(distance, limit: self.endIndex) } 
      return index != self.endIndex ? Array(self[index ..< index.advancedBy(distance, limit: self.endIndex)]) : nil 
     } 
     return Array(generator) 
    } 

} 

Das Xcode-Konvertierungs-Werkzeug mir dabei links zu konvertieren.

extension Collection { 

    func chunk(withDistance distance: Int) -> [[SubSequence.Iterator.Element]] { 
     var index = startIndex 
     let generator: AnyGenerator<Array<SubSequence.Generator.Element>> = anyGenerator { 
      defer { index = index.advancedBy(distance, limit: self.endIndex) } 
      return index != self.endIndex ? Array(self[index ..< index.advancedBy(distance, limit: self.endIndex)]) : nil 
     } 
     return Array(generator) 
    } 

} 

Jetzt bin immer ich den obigen Fehler in Zeile, let generator: AnyGenerator<Array<SubSequence.Generator.Element>> = anyGenerator {. Ich kann nicht herausfinden, wie ich das beheben kann.

Antwort

1

Es gibt mehrere Probleme:

  • Generator zu Iterator in Swift 3 umbenannt wurde, und folglich AnyGenerator zu AnyIterator.
  • IndexDistance ist der zugehörige Typ Collection, der die Anzahl der Schritte zwischen den Indizes darstellt.
  • In Swift 3, "Sammlungen bewegen ihren Index", siehe A New Model for Collections and Indices auf Swift Evolution.

es Putting alles zusammen, könnte Ihre Methode aussehen in Swift 3 wie folgt aus:

extension Collection { 

    func chunk(withDistance distance: IndexDistance) -> [[SubSequence.Iterator.Element]] { 
     var pos = startIndex 
     let iterator: AnyIterator<Array<SubSequence.Iterator.Element>> = AnyIterator { 
      // Already at the end? 
      if pos == self.endIndex { return nil } 

      // Compute `pos + distance`, but not beyond `self.endIndex`: 
      let endPos = self.index(pos, offsetBy: distance, limitedBy: self.endIndex) ?? self.endIndex 

      // Return chunk and advance `pos`: 
      defer { pos = endPos } 
      return Array(self[pos..<endPos]) 
     } 
     return Array(iterator) 
    } 
} 

let a = [1, 2, 3, 4, 5, 6, 7] 
let c = a.chunk(withDistance: 2) 
print(c) // [[1, 2], [3, 4], [5, 6], [7]] 

ich die lokale index Variable pos umbenannt, Verwirrung mit der

public func index(_ i: Self.Index, offsetBy n: Self.IndexDistance, limitedBy limit: Self.Index) -> Self.Index? 
zu vermeiden

Methode von Collection, die verwendet wird, um den Index zu erweitern.

Natürlich könnte man das gleiche Ergebnis mit einer while Schleife anstelle eines Iterator erreichen:

extension Collection { 

    func chunk(withDistance distance: IndexDistance) -> [[SubSequence.Iterator.Element]] { 
     var result: [[SubSequence.Iterator.Element]] = [] 
     var pos = startIndex 
     while pos != endIndex { 
      let endPos = self.index(pos, offsetBy: distance, limitedBy: self.endIndex) ?? self.endIndex 
      result.append(Array(self[pos..<endPos])) 
      pos = endPos 
     } 
     return result 
    } 
} 
+0

Danke. Ihr zweiter Ansatz ist viel sauberer und leichter zu verstehen. – Isuru

Verwandte Themen