513 Stimmen

Erhalten Sie das n-te Zeichen eines Strings in Swift

Wie kann ich das n-te Zeichen einer Zeichenkette erhalten? Ich habe es mit dem eckigen Klammern ([]) Operator versucht, aber es hat nicht geklappt.

var string = "Hallo, Welt!"

var firstChar = string[0] // Wirft einen Fehler

FEHLER: 'subscript' ist nicht verfügbar: String kann nicht mit einem Int indiziert werden, siehe den Dokumentationskommentar für weitere Informationen

1voto

Marcin Kapusta Punkte 4412

Sie können auch String in ein Array von Zeichen konvertieren, wie folgt:

let text = "Mein Text"
let index = 2
let charSequence = text.unicodeScalars.map{ Character($0) }
let char = charSequence[index]

Das ist der Weg, um das Zeichen an der angegebenen Stelle in konstanter Zeit zu erhalten.

Das folgende Beispiel läuft nicht in konstanter Zeit, sondern erfordert lineare Zeit. Wenn Sie also viel nach einem Zeichen in einem String nach Index suchen, verwenden Sie die obige Methode.

let char = text[text.startIndex.advancedBy(index)]

1voto

Joseph Merdrignac Punkte 2880

Eine pythonähnliche Lösung, die es ermöglicht, einen negativen Index zu verwenden,

var str = "Hallo Welt!"
str[-1]        // "!"

könnte sein:

extension String {
    subscript (var index:Int)->Character{
        get {
            let n = distance(self.startIndex, self.endIndex)
            index %= n
            if index < 0 { index += n }
            return self[advance(startIndex, index)]
        }
    }
}

Übrigens könnte es sich lohnen, die gesamte Python-Slice-Notation zu übernehmen

1voto

Luc-Olivier Punkte 3288

Um das Thema zu füttern und schnelle Subskriptmöglichkeiten zu zeigen, hier noch ein kleiner String "substring-toolbox" im Index

Diese Methoden sind sicher und überschreiten niemals die String-Indizes

extension String {
    // string[i] -> ein Zeichen
    subscript(pos: Int) -> String { return String(Array(self)[min(self.length-1,max(0,pos))]) }

    // string[pos, len] -> Unterstring von pos für len Zeichen auf der linken Seite
    subscript(pos: Int, len: Int) -> String { return self[pos, len, .pos_len, .left2right] }

    // string[pos, len, .right2left] -> Unterstring von pos für len Zeichen auf der rechten Seite
    subscript(pos: Int, len: Int, way: Way) -> String { return self[pos, len, .pos_len, way] }

    // string[range] -> Unterstring von Anfangsposition auf der linken Seite bis Endposition auf der rechten Seite
    subscript(range: Range) -> String { return self[range.startIndex, range.endIndex, .start_end, .left2right] }

    // string[range, .right2left] -> Unterstring von Anfangsposition auf der rechten Seite bis Endposition auf der linken Seite
    subscript(range: Range, way: Way) -> String { return self[range.startIndex, range.endIndex, .start_end, way] }

    var length: Int { return countElements(self) }
    enum Mode { case pos_len, start_end }
    enum Way { case left2right, right2left }
    subscript(var val1: Int, var val2: Int, mode: Mode, way: Way) -> String {
        if mode == .start_end {
            if val1 > val2 { let val=val1 ; val1=val2 ; val2=val }
            val2 = val2-val1
        }
        if way == .left2right {
            val1 = min(self.length-1, max(0,val1))
            val2 = min(self.length-val1, max(1,val2))
        } else {
            let val1_ = val1
            val1 = min(self.length-1, max(0, self.length-val1_-val2 ))
            val2 = max(1, (self.length-1-val1_)-(val1-1) )
        }
        return self.bridgeToObjectiveC().substringWithRange(NSMakeRange(val1, val2))

        //-- Alternativer Code ohne bridge --
        //var range: Range = pos...(pos+len-1)
        //var start = advance(startIndex, range.startIndex)
        //var end = advance(startIndex, range.endIndex)
        //return self.substringWithRange(Range(start: start, end: end))
    }
}

println("0123456789"[3]) // gibt "3" zurück

println("0123456789"[3,2]) // gibt "34" zurück

println("0123456789"[3,2,.right2left]) // gibt "56" zurück

println("0123456789"[5,10,.pos_len,.left2right]) // gibt "56789" zurück

println("0123456789"[8,120,.pos_len,.right2left]) // gibt "01" zurück

println("0123456789"[120,120,.pos_len,.left2right]) // gibt "9" zurück

println("0123456789"[0...4]) // gibt "01234" zurück

println("0123456789"[0..4]) // gibt "0123" zurück

println("0123456789"[0...4,.right2left]) // gibt "56789" zurück

println("0123456789"[4...0,.right2left]) // gibt "678" zurück << weil ??? Bereich kann EndIndex von 0 haben ???

0voto

Daniele Ceglia Punkte 830

Swift 3:

extension String {
    func substring(fromPosition: UInt, toPosition: UInt) -> String? {
        guard fromPosition <= toPosition else {
            return nil
        }

        guard toPosition < UInt(characters.count) else {
            return nil
        }

        let start = index(startIndex, offsetBy: String.IndexDistance(fromPosition))
        let end   = index(startIndex, offsetBy: String.IndexDistance(toPosition) + 1)
        let range = start..

0voto

Jay Harris Punkte 4201

Erlaubt negative Indizes

Es ist immer nützlich, nicht immer string[string.length - 1] schreiben zu müssen, um das letzte Zeichen bei Verwendung einer Index-Erweiterung zu erhalten. Diese (Swift 3) Erweiterung erlaubt negative Indizes, Bereich und CountableClosedRange.

extension String {
    var count: Int { return self.characters.count }

    subscript (i: Int) -> Character {
        // Wraps out of bounds indices
        let j = i % self.count
        // Wraps negative indices
        let x = j < 0 ? j + self.count : j

        // Schneller Ausstieg für erstes Zeichen
        guard x != 0 else {
            return self.characters.first!
        }

        // Schneller Ausstieg für letztes Zeichen
        guard x != count - 1 else {
            return self.characters.last!
        }

        return self[self.index(self.startIndex, offsetBy: x)]
    }

    subscript (r: Range) -> String {
        let lb = r.lowerBound
        let ub = r.upperBound

        // Schneller Ausstieg für ein Zeichen
        guard lb != ub else { return String(self[lb]) }

        return self[self.index(self.startIndex, offsetBy: lb)..) -> String {
        return self[r.lowerBound..

``So kannst du es verwenden:

var text = "Hello World"

text[-1]    // d
text[2]     // l
text[12]    // e
text[0...4] // Hello
text[0..<4] // Hell

Für den gründlicheren Programmierer: Füge eine guard gegen leere Strings in dieser Erweiterung hinzu

subscript (i: Int) -> Character {
    guard self.count != 0 else { return '' }
    ...
}

subscript (r: Range) -> String {
    guard self.count != 0 else { return "" }
    ...
}``

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X