Ecco un'estensione che ti permetterà di accedere ai limiti di una sottostringa come Int
s invece che come String.Index
valori:
import Foundation
extension StringProtocol {
func countableRange<SearchType: StringProtocol>(
of search: SearchType,
options: String.CompareOptions = [],
range: Range<String.Index>? = nil,
locale: Locale? = nil
) -> CountableRange<Int>? {
guard let trueRange = self.range(of: search, options: options, range: range, locale: locale) else {
return nil
}
let intStart = self.distance(from: startIndex, to: trueRange.lowerBound)
let intEnd = self.distance(from: trueRange.lowerBound, to: trueRange.upperBound) + intStart
return Range(uncheckedBounds: (lower: intStart, upper: intEnd))
}
}
Basta essere consapevoli che questo può portare a stranezze, motivo per cui Apple ha scelto di renderlo difficile. (Anche se è una decisione progettuale discutibile: nascondere una cosa pericolosa semplicemente rendendola difficile ...)
Puoi leggere di più nella documentazione String di Apple , ma il tldr è che deriva dal fatto che questi "indici" sono in realtà specifici dell'implementazione. Rappresentano gli indici nella stringa dopo che è stata renderizzata dal sistema operativo e quindi possono passare da sistema operativo a sistema operativo a seconda della versione della specifica Unicode utilizzata. Ciò significa che l'accesso ai valori in base all'indice non è più un'operazione a tempo costante, perché la specifica UTF deve essere eseguita sui dati per determinare il posto giusto nella stringa. Questi indici inoltre non si allineeranno con i valori generati da NSString, se si collega ad esso, o con gli indici negli scalari UTF sottostanti. Sviluppatore avvertimento.