Wie kann ich das n-te Zeichen einer Zeichenfolge erhalten? Ich habe versucht, Bracket ( []
) Accessor ohne Glück.
var string = "Hello, world!"
var firstChar = string[0] // Throws error
FEHLER: 'tiefgestellt' ist nicht verfügbar: Zeichenkette kann nicht mit einem Int abonniert werden. Weitere Informationen finden Sie im Dokumentationskommentar
swift
string
collections
character
Mohsen
quelle
quelle
var firstChar = string.index(string.startIndex, offsetBy: 0)
stattdessenstring.startIndex
? Für das erste Zeichenstring[string.startIndex]
oder einfachstring.first
. Beachten Sie, dass der erste Ansatz, den Sie benötigen würden, um zu überprüfen, ob die Zeichenfolge zuerst leer ist, der zweite ein optionales zurückgibtAntworten:
Achtung: Bitte beachten Sie Leo Dabus' Antwort für eine ordnungsgemäße Durchführung für Swift 4 und Swift 5.
Swift 4 oder höher
Der
Substring
Typ wurde in Swift 4 eingeführt, um Teilzeichenfolgen schneller und effizienter zu machen, indem der Speicher mit der ursprünglichen Zeichenfolge geteilt wird. Daher sollten die Indexfunktionen dies zurückgeben.Probieren Sie es hier aus
Um das
Substring
in ein zu konvertierenString
, können Sie dies einfach tunString(string[0..2])
, aber Sie sollten dies nur tun, wenn Sie vorhaben, die Teilzeichenfolge beizubehalten. Ansonsten ist es effizienter, es zu behaltenSubstring
.Es wäre großartig, wenn jemand einen guten Weg finden könnte, diese beiden Erweiterungen zu einer zusammenzuführen. Ich habe versucht,Hinweis: Diese Antwort wurde bereits bearbeitet, ist ordnungsgemäß implementiert und funktioniert jetzt auch für Teilzeichenfolgen. Stellen Sie einfach sicher, dass Sie einen gültigen Bereich verwenden, um Abstürze beim Abonnieren Ihres StringProtocol-Typs zu vermeiden. Für die Subskription mit einem Bereich, der nicht mit Werten außerhalb des Bereichs abstürzt, können Sie diese Implementierung verwendenStringProtocol
ohne Erfolg zu erweitern, da dieindex
Methode dort nicht existiert.Warum ist das nicht eingebaut?
Die Fehlermeldung lautet "Siehe den Dokumentationskommentar zur Diskussion" . Apple bietet die folgende Erklärung in der Datei UnavailableStringAPIs.swift :
quelle
Cannot find an overload for 'advance' that accepts an argument list of type '(String.Index, T)'
...String.Index
undInt
sind nicht kompatibel.Cannot subscript a value of type 'String'...
überprüfen Sie diese Antwort: stackoverflow.com/a/31265316/649379Ambiguous use of 'subscript'
.fatal error: Can't form a Character from an empty String
Swift 5.2
Sie müssen diese String-Erweiterung zu Ihrem Projekt hinzufügen (es ist vollständig getestet):
Auch wenn Swift für dieses Problem immer eine sofort einsatzbereite Lösung hatte (ohne die unten angegebene String-Erweiterung), würde ich die Verwendung der Erweiterung nachdrücklich empfehlen . Warum? Weil es mir Dutzende Stunden schmerzhafter Migration von früheren Versionen von Swift erspart hat, bei denen die Syntax von String fast jede Version geändert hat, aber alles, was ich tun musste, war, die Implementierung der Erweiterung zu aktualisieren, anstatt das gesamte Projekt umzugestalten. Treffen Sie Ihre Wahl.
quelle
range.upperBound - range.lowerBound
zurange.count
extension StringProtocol where Self: RangeReplaceableCollection { subscript(offset: Int) -> Element { get { return self[index(startIndex, offsetBy: offset)] } set { let start = index(startIndex, offsetBy: offset) replaceSubrange(start..<index(after: start), with: [newValue]) } } }
Ich habe mir gerade diese nette Problemumgehung ausgedacht
quelle
var firstChar = Array(string!)[0]
Andernfalls heißt esadd arrayLiteral
Keine Indizierung mit ganzen Zahlen, nur mit
String.Index
. Meist mit linearer Komplexität. Sie können damit auch Bereiche erstellenString.Index
und Teilzeichenfolgen abrufen.Swift 3.0
Swift 2.x.
Beachten Sie, dass Sie niemals einen Index (oder Bereich) verwenden können, der von einer Zeichenfolge zu einer anderen Zeichenfolge erstellt wurde
quelle
String
Indizes sind für eine Zeichenfolge eindeutig. Dies liegt daran, dass unterschiedliche Zeichenfolgen unterschiedliche UTF-16-Einheiten mit mehreren EinheitenCharacters
und / oder unterschiedliche Positionen aufweisen können, sodass die UTF-16-Einheitenindizes nicht übereinstimmen und möglicherweise über das Ende oder den Punkt innerhalb einer UTF-16-Einheit mit mehreren Einheiten hinausgehenCharacter
...
ist jetzt..<
(in Ihrer Aufgabe zurange
)var lastChar = string[string.endIndex.predecessor()]
Xcode 11 • Swift 5.1
Sie können StringProtocol erweitern, um den Index auch für die Teilzeichenfolgen verfügbar zu machen:
Testen
quelle
return String(Array(characters)[range])
Swift 3?Swift 4
Zeichenfolge am Index
Teilstring
Erste n Zeichen
Letzte n Zeichen
Swift 2 und 3
** String am Index **
Swift 2
Swift 3
SubString fromIndex toIndex
Swift 2
Swift 3
Erste n Zeichen
Letzte n Zeichen
quelle
Swift 2.0 ab Xcode 7 GM Seed
Ersetzen Sie für das n-te Zeichen 0 durch n-1.
Bearbeiten: Swift 3.0
nb Es gibt einfachere Möglichkeiten, bestimmte Zeichen in der Zeichenfolge zu erfassen
z.B
let firstChar = text.characters.first
quelle
Wenn Sie sehen,
Cannot subscript a value of type 'String'...
verwenden Sie diese Erweiterung:Swift 3
Swift 2.3
Quelle: http://oleb.net/blog/2014/07/swift-strings/
quelle
Swift 2.2 Lösung:
Die folgende Erweiterung funktioniert in Xcode 7, dies ist eine Kombination aus dieser Lösung und der Swift 2.0-Syntaxkonvertierung.
quelle
Die Swift-String-Klasse bietet aufgrund ihrer nativen Unterstützung für UTF-Zeichen keine Möglichkeit, ein Zeichen an einem bestimmten Index abzurufen. Die variable Länge eines UTF-Zeichens im Speicher macht es unmöglich, direkt zu einem Zeichen zu springen. Das bedeutet, dass Sie die Zeichenfolge jedes Mal manuell durchlaufen müssen.
Sie können String erweitern, um eine Methode bereitzustellen, die die Zeichen bis zu Ihrem gewünschten Index durchläuft
quelle
myString.bridgeToObjectiveC().characterAtIndex(0)
oder(string as NSString ).characterAtIndex(0)
gibt einen Int-Wert des Zeichens zurückNSString
Methoden für den Zugriff auf einzelne Zeichen von einem Swift-Native ausString
- die beiden verwenden unterschiedliche Zählmechanismen, sodass Sie mit höheren Unicode-Zeichen unvorhersehbare Ergebnisse erzielen. Die erste Methode sollte sicher sein (sobald die Unicode-Fehler von Swift behoben sind).Nebenbei bemerkt, es gibt einige Funktionen, die direkt auf die Zeichenkettendarstellung eines Strings anwendbar sind:
Das Ergebnis ist vom Typ Character, aber Sie können es in einen String umwandeln.
Oder dieses:
:-)
quelle
Swift 4
Dies ist wahrscheinlich der beste Weg, um dieses Problem einmalig zu lösen. Sie möchten den String wahrscheinlich zuerst als Array und dann erneut als String umwandeln. Andernfalls wird anstelle eines Strings ein Zeichen zurückgegeben.
Beispiel
String(Array("HelloThere")[1])
gibt "e" als String zurück.(Array("HelloThere")[1]
gibt "e" als Zeichen zurück.Swift erlaubt es nicht, Strings wie Arrays zu indizieren, aber dies erledigt den Job im Brute-Force-Stil.
quelle
Meine sehr einfache Lösung:
Swift 4.1:
Swift 5.1:
quelle
let flags = "🇺🇸🇧🇷"
flags[String.Index(utf16Offset: 4, in: flags)] // "🇧🇷"
Sie können dies tun, indem Sie String in Array konvertieren und ihn anhand eines Index gemäß dem folgenden Index abrufen
quelle
Ich hatte gerade das gleiche Problem. Mach das einfach:
quelle
NSString
.Swift3
Sie können die tiefgestellte Syntax verwenden, um auf das Zeichen an einem bestimmten Zeichenfolgenindex zuzugreifen.
Besuch https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html
oder wir können eine String-Erweiterung in Swift 4 durchführen
VERWENDUNGSZWECK:
quelle
Meine Lösung ist in einer Zeile, vorausgesetzt, Kadena ist die Zeichenfolge und 4 ist die n-te Position, die Sie möchten:
Einfach ... Ich nehme an, Swift wird in zukünftigen Versionen mehr über Teilzeichenfolgen enthalten.
quelle
var charAtIndex = string[advance(string.startIndex, 10)]
in Sulthans Antwort?Swift 3: eine andere Lösung (auf dem Spielplatz getestet)
Verwendungszweck:
quelle
Update für Swift 2.0 SubString
quelle
Ich denke, dass eine schnelle Antwort für den ersten Charakter sein könnte:
Es ist so viel eleganter und leistungsfähiger als:
Aber ... wenn Sie manipulieren und mehr Operationen mit Zeichenfolgen ausführen möchten, könnten Sie denken, dass Sie eine Erweiterung erstellen. Es gibt eine Erweiterung mit diesem Ansatz, die der bereits hier veröffentlichten ziemlich ähnlich ist:
}}
ABER ES IST EINE SCHRECKLICHE IDEE !!
Die Erweiterung unten ist schrecklich ineffizient. Jedes Mal, wenn auf eine Zeichenfolge mit einer Ganzzahl zugegriffen wird, wird eine O (n) -Funktion zum Vorrücken des Startindex ausgeführt. Das Ausführen einer linearen Schleife innerhalb einer anderen linearen Schleife bedeutet, dass diese for-Schleife versehentlich O (n2) ist. Mit zunehmender Länge der Zeichenfolge nimmt die Zeit, die diese Schleife benötigt, quadratisch zu.
Stattdessen können Sie die Zeichenfolgensammlung der Zeichen verwenden.
quelle
Swift 3
Verwendungszweck
Hilfreiche Tipps und Tricks zur Programmierung (von mir geschrieben)
quelle
Index abrufen und festlegen (String & Teilzeichenfolge) - Swift 4.2
Swift 4.2, Xcode 10
Ich habe meine Antwort auf die Antwort von @alecarlson gestützt . Der einzige große Unterschied besteht darin, dass Sie eine
Substring
oder eineString
Rückgabe (und in einigen Fällen eine einzelneCharacter
) erhalten können. Sie können auchget
undset
den Index. Schließlich ist meine etwas umständlicher und länger als die Antwort von @alecarlson , und als solche schlage ich vor, dass Sie sie in eine Quelldatei einfügen .Erweiterung:
quelle
Swift 4.2
Diese Antwort ist ideal, weil sie
String
alleSubsequences
(Substring
) in einer Erweiterung erweitertVerwendungszweck
quelle
start
undend
) unnötigerweise von derstartIndex
. Sie können denend
Index einfach mit dem range.count versetzen und denstart
IndexInzwischen ist der Index (_ :) nicht verfügbar. Sowie wir das nicht können
mit string.Wir müssen "String.Index" angeben. Aber wie können wir auf diese Weise unsere eigene Indexnummer angeben, stattdessen können wir verwenden:
quelle
string[string.startIndex]
? Übrigens würde sich der Code nicht korrekt verhalten / kompilieren, da Sie zwei verschiedene Variablennamen verwendet haben.Swift 4.2 oder höher
Bereichs- und Teilbereichsabonnement mit
String
'sindices
EigenschaftAls Variation der netten Antwort von @LeoDabus können wir eine zusätzliche Erweiterung hinzufügen, um
DefaultIndices
bei der Implementierung der benutzerdefinierten Indizes (nach speziellen Bereichen und Teilbereichen) für letztere auf dieindices
Eigenschaft zurückgreifen zu können .String
Int
Vielen Dank an @LeoDabus für den Hinweis, dass ich die
indices
Eigenschaft als (andere) Alternative zumString
Abonnieren verwenden soll!quelle
swiftenv
wenn ich es tue, aber ich denke, es wird dann auch etwas bald mit 4.2 aktualisiert.Swift 5.1.3:
Fügen Sie eine String-Erweiterung hinzu:
quelle
Swifts
String
Typ bietet keinecharacterAtIndex
Methode, da eine Unicode-Zeichenfolge auf verschiedene Arten codiert werden kann. Gehst du mit UTF8, UTF16 oder etwas anderem?Sie können auf die
CodeUnit
Sammlungen zugreifen, indem Sie die EigenschaftenString.utf8
undString.utf16
abrufen. Sie können auch auf dieUnicodeScalar
Sammlung zugreifen, indem Sie die abrufenString.unicodeScalars
Eigenschaft .Im Geiste der
NSString
Implementierung gebe ich einenunichar
Typ zurück.quelle
Um das Thema zu füttern und schnelle Indexmöglichkeiten aufzuzeigen, finden Sie hier eine kleine Zeichenfolge, die auf dem Index "substring-toolbox" basiert
Diese Methoden sind sicher und gehen niemals über String-Indizes
quelle
Eine Python-ähnliche Lösung, mit der Sie einen negativen Index verwenden können.
könnte sein:
Übrigens kann es sich lohnen, die Slice-Notation der gesamten Python zu transponieren
quelle
Sie können String auch wie folgt in ein Array von Zeichen konvertieren:
Dies ist der Weg, um char in konstanter Zeit am angegebenen Index zu erhalten.
Das folgende Beispiel läuft nicht in konstanter Zeit, sondern erfordert lineare Zeit. Wenn Sie in String nach Index viel suchen, verwenden Sie die oben beschriebene Methode.
quelle