Es ist Zeit, eine Niederlage zuzugeben ...
In Objective-C könnte ich Folgendes verwenden:
NSString* str = @"abcdefghi";
[str rangeOfString:@"c"].location; // 2
In Swift sehe ich etwas Ähnliches:
var str = "abcdefghi"
str.rangeOfString("c").startIndex
... aber das gibt mir nur eine String.Index
, mit der ich die ursprüngliche Zeichenfolge zurückschreiben, aber keinen Ort daraus extrahieren kann.
FWIW, das String.Index
hat einen privaten ivar namens _position
, der den richtigen Wert enthält. Ich sehe nur nicht, wie es ausgesetzt ist.
Ich weiß, dass ich dies leicht selbst zu String hinzufügen könnte. Ich bin neugieriger auf das, was mir in dieser neuen API fehlt.
Antworten:
Sie sind nicht der einzige, der die Lösung nicht finden konnte.
String
nicht implementiertRandomAccessIndexType
. Wahrscheinlich, weil sie Zeichen mit unterschiedlichen Bytelängen aktivieren. Deshalb müssen wirstring.characters.count
(count
odercountElements
in Swift 1.x) verwenden, um die Anzahl der Zeichen zu erhalten. Das gilt auch für Positionen. Das_position
ist wahrscheinlich ein Index in das rohe Array von Bytes und sie wollen das nicht offenlegen. DasString.Index
soll uns vor dem Zugriff auf Bytes in der Mitte von Zeichen schützen.Das bedeutet, dass jeder Index, den Sie erhalten, aus
String.startIndex
oderString.endIndex
(String.Index
implementiertBidirectionalIndexType
) erstellt werden muss. Alle anderen Indizes können mitsuccessor
oderpredecessor
Methoden erstellt werden .Um uns bei den Indizes zu helfen, gibt es eine Reihe von Methoden (Funktionen in Swift 1.x):
Swift 4.x.
Swift 3.0
Swift 2.x.
Swift 1.x.
Das Arbeiten mit
String.Index
ist umständlich, aber die Verwendung eines Wrappers zum Indizieren nach Ganzzahlen (siehe https://stackoverflow.com/a/25152652/669586 ) ist gefährlich, da dadurch die Ineffizienz einer echten Indizierung verborgen wird.Beachten Sie, dass die Swift-Indizierungsimplementierung das Problem hat, dass für eine Zeichenfolge erstellte Indizes / Bereiche nicht zuverlässig für eine andere Zeichenfolge verwendet werden können. Beispiel:
Swift 2.x.
Swift 1.x.
quelle
range
invar range = text.rangeOfString("b")
Collection
hat einetypealias IndexType
. Für Arrays ist es definiert alsInt
, dennString
es ist definiert alsString.Index
. Sowohl Arrays als auch Strings können auch Bereiche verwenden (um Subarrays und Teilzeichenfolgen zu erstellen). Das Sortiment ist ein besonderer TypRange<T>
. Für Strings ist esRange<String.Index>
für ArraysRange<Int>
.Swift 2.0
,distance(text.startIndex, range.startIndex)
wirdtext.startIndex.distanceTo(range.startIndex)
String
hat genau wieNSString
in Foundation eine Methode namenshasPrefix(_:)
.Swift 3.0 macht dies etwas ausführlicher:
Erweiterung:
In Swift 2.0 ist dies einfacher geworden:
Erweiterung:
Schnelle 1.x-Implementierung:
Für eine reine Swift-Lösung kann man verwenden:
Als Erweiterung zu
String
:quelle
quelle
Ich habe diese Lösung für swift2 gefunden:
quelle
Swift 5.0
Swift 4.0
quelle
Ich bin nicht sicher, wie ich die Position aus String.Index extrahieren soll, aber wenn Sie bereit sind, auf einige Objective-C-Frameworks zurückzugreifen, können Sie eine Brücke zu Objective-C schlagen und dies auf die gleiche Weise tun, wie Sie es früher getan haben.
Es scheint, dass einige NSString-Methoden noch nicht auf String portiert wurden (oder werden). Enthält auch in den Sinn.
quelle
bridgeToObjectiveC()
Aufruf nicht benötigt wird. Mein Problem scheint sich nur beim Aufrufen einesrangeOfString
zuvor vorhandenen Swift-Strings zu manifestieren . Scheint wie ein API-Problem ...Hier ist eine saubere String-Erweiterung, die die Frage beantwortet:
Swift 3:
Swift 2.2:
quelle
Sie können auch Indizes eines Zeichens in einer einzelnen Zeichenfolge wie folgt finden:
Was das Ergebnis in [String.Distance] ergibt, dh. [Int], wie
quelle
Wenn Sie vertrautes NSString verwenden möchten, können Sie es explizit deklarieren:
Ich bin mir noch nicht sicher, wie ich das in Swift machen soll.
quelle
Wenn Sie die Position eines Zeichens in einer Zeichenfolge als int- Wert kennen möchten, verwenden Sie Folgendes :
quelle
value of type 'Range<String.Index>?' has no member 'location'
.Ich weiß, dass dies alt ist und eine Antwort akzeptiert wurde, aber Sie können den Index der Zeichenfolge in ein paar Codezeilen finden, indem Sie:
Einige andere großartige Informationen zu Swift-Strings hier Strings in Swift
quelle
find
ist nicht verfügbar in Swift 3Das hat bei mir funktioniert,
das hat auch funktioniert,
quelle
var str = "abcdef"; str.rangeOfString("c").location
löst einen Fehler über String.Index aus, der kein Mitglied mit dem Namen location hat ...Der Variablentyp String in Swift enthält andere Funktionen als NSString in Objective-C. Und wie Sulthan erwähnte,
Was Sie tun können, ist, Ihre Variable vom Typ String auf NSString herunterzuspielen (dies gilt in Swift). Dadurch erhalten Sie Zugriff auf die Funktionen in NSString.
quelle
Wenn Sie darüber nachdenken, benötigen Sie die genaue Int-Version des Speicherorts nicht wirklich. Der Bereich oder sogar der String.Index reicht aus, um den Teilstring bei Bedarf wieder herauszuholen:
quelle
Der einfachste Weg ist:
In Swift 3 :
quelle
String ist ein Brückentyp für NSString
in Ihre schnelle Datei und verwenden Sie alle "alten" Methoden.
quelle
In Bezug auf das Denken könnte dies eine INVERSION genannt werden. Sie entdecken, dass die Welt rund statt flach ist. "Du musst den INDEX des Charakters nicht wirklich kennen, um Dinge damit zu machen." Und als C-Programmierer fand ich das auch schwer zu ertragen! Ihre Zeile "let index = letter.characters.indexOf (" c ")!" ist genug für sich. Zum Beispiel, um das c zu entfernen, könnten Sie verwenden ... (Spielplatz einfügen)
Wenn Sie jedoch einen Index möchten, müssen Sie einen tatsächlichen INDEX zurückgeben, nicht einen Int, da ein Int-Wert zusätzliche Schritte für jede praktische Verwendung erfordern würde. Diese Erweiterungen geben einen Index, eine Anzahl eines bestimmten Zeichens und einen Bereich zurück, den dieser Plug-in-fähige Spielplatzcode demonstriert.
quelle
Swift 4 Komplettlösung:
OffsetIndexableCollection (Zeichenfolge mit Int-Index)
https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-
quelle
Erweiterungszeichenfolge {
}}
quelle
Swift 5
Index der Teilzeichenfolge suchen
Index des Charakters finden
quelle
Wenn Sie nach einer einfachen Möglichkeit suchen, einen Index für Zeichen oder Zeichenfolgen zu erhalten, lesen Sie diese Bibliothek unter http://www.dollarswift.org/#indexof-char-character-int
Sie können den indexOf aus einer Zeichenfolge auch mit einer anderen Zeichenfolge oder einem Regex-Muster abrufen
quelle
So erhalten Sie mit Swift 2 den Index eines Teilstrings in einem String:
quelle
In schnell 2.0
quelle
quelle
Ich spiele mit folgendem
Bis ich das bereitgestellte verstehe, ist es nur ein Zeichenarray
und mit
quelle
Wenn Sie nur den Index eines Zeichens benötigen, ist die einfachste und schnellste Lösung (wie bereits von Pascal ausgeführt):
quelle
In Bezug auf das Verwandeln von a
String.Index
in aInt
funktioniert diese Erweiterung für mich:Beispiel für eine Verwendung, die für diese Frage relevant ist:
Wichtig:
Wie Sie sehen können, werden erweiterte Graphemcluster und verbundene Zeichen anders gruppiert als
String.Index
. Das ist natürlich der Grund, warum wir habenString.Index
. Beachten Sie, dass bei dieser Methode Cluster als einzelne Zeichen betrachtet werden, was näher an der Korrektur liegt. Wenn Sie eine Zeichenfolge nach Unicode-Codepunkt aufteilen möchten, ist dies nicht die Lösung für Sie.quelle
In Swift 2.0 gibt die folgende Funktion einen Teilstring vor einem bestimmten Zeichen zurück.
quelle
Sie können die Indexnummer eines Zeichens in einer Zeichenfolge folgendermaßen finden:
quelle
Aus meiner Sicht ist der bessere Weg, die Logik selbst zu kennen, unten
quelle