2016-06-28 13 views
1

Ich implementiere eine Erweiterung für Swift's CollectionType, die die Möglichkeit bietet, eine Untersequenz in der Sammlung zu finden und den Bereich dieser Untersequenz zu finden. Mein Code, der auf einem Spielplatz arbeiten ist, ist dies:Swift-Index, Bereich, Entfernung verstehen

extension CollectionType where Generator.Element:Equatable, Index:ForwardIndexType, SubSequence.Generator.Element == Generator.Element { 
    func search<S: CollectionType where S.Generator.Element == Generator.Element, S.Index:ForwardIndexType>(pattern: S) -> Self.Index? { 
     return self.lazy.indices.indexOf{ 
      self[$0..<self.endIndex].startsWith(pattern) 
     } 
    } 

    func rangeOf<S: CollectionType where S.Generator.Element == Generator.Element, S.Index:ForwardIndexType, Index:ForwardIndexType>(pattern: S) -> Range<Index>? { 
     if let start = self.search(pattern) { 
      var end = start 
      for _ in pattern.startIndex..<pattern.endIndex { 
       end = end.advancedBy(1) 
      } 
      return start..<end 
     } else { 
      return nil 
     } 
    } 
} 

Einfache Spielplatz Testfälle sind diese:

let fibs = [1, 1, 2, 3, 5, 8, 13] 
if let fidx = fibs.search([3, 5]) { 
    print(fibs[..<fidx])       // prints "[1, 1, 2]\n" 
    print(fidx..<fidx.advancedBy([1,1,5].count)) // prints "3..<6\n" 
} 
if let rng = fibs.rangeOf([5,8,13]) { 
    print(rng)         // prints "4..<7\n" 
} 

jedoch in der gängigen Portfolio-Funktion anstelle der Schleife

  for _ in pattern.startIndex..<pattern.endIndex { 
       end = end.advancedBy(1) 
      } 

I Es wird erwartet, dass die Anweisung

  end = start.advancedBy(pattern.count, limit: self.endIndex) 
verwendet werden kann

oder vielleicht

  end = start.advancedBy(pattern.endIndex - pattern.startIndex, limit: self.endIndex) 

(ich erkenne, dass der Grenzwert Parameter ist überflüssig; das Weglassen macht im Folgenden keinen Unterschied.) Keines der beiden letzten kompiliert mit dem Fehler cannot invoke 'advancedBy' with an argument list of type '(S.Index.Distance, limit: Self.Index)'. Meine Frage ist, warum ist keine dieser beiden Formen akzeptabel? (Ich nehme an, es gibt auch andere berechtigte Fragen, ob ich habe richtig die Einschränkungen für Typen für die Erweiterung und für die Funktionen gebildet werden, aber da die einer Version arbeite ich ignoriere, dass für jetzt.)

Antwort

1
end = start.advancedBy(pattern.count, limit: self.endIndex) 

kompiliert nicht, weil die Sammlungen self und pattern brauchen, haben Sie nicht den gleichen Index Typ.

Es wird kompiliert, wenn Sie der Methode rangeOf() eine Integritätsbedingung S.Index == Index hinzufügen.

+0

Nachdem ich das behoben hatte, entdeckte ich, dass ich viele andere Einschränkungen entfernen konnte. Nett. – Feldur