Swift Substring to String Conversion

Swift Substring to String Conversion

Deze snaaroperaties in Swift kunnen je gek maken, zelfs als je gewend bent aan een eenvoudige van C#. Daarom heb ik er naar gekeken en een beetje van dit alles in elkaar gezet. Dit werd getest met Swift 5.1

  • startIndex is de index van het eerste teken
  • endIndex is de index na het laatste teken
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let str = "Hello, playground"
        print(str[str.startIndex]) // H
        //print(str[str.endIndex])   // error: after last character

        let rangeStartToEnd = str.startIndex..<str.endIndex
        print("Range: " + str[rangeStartToEnd])  // "Hello, playground"

        let rangeWithoutGround = str.startIndex..<str.index(of: "ground")!
        print("Range: " + str[rangeWithoutGround])  // "Hello, playground"
    }

verwijst naar de index van het teken direct voor de gespecificeerde index.

// character
let index = str.index(before: str.endIndex)
str[index]  // d

// range
let range = str.startIndex..<str.index(before: str.endIndex)
str[range]  // Hello, playgroun

De OffsetBy waarde kan positief of negatief zijn en begint met de gespecificeerde index. Hoewel het van het type String.IndexDistance is, kunt u een Int-waarde doorgeven.

De limitedBy is nuttig om ervoor te zorgen dat de offset niet leidt tot overschrijding van de limieten van de index. Het is een limietindex. Aangezien het mogelijk is dat de offset de grenswaarde overschrijdt, geeft deze methode een optioneel karakter. Het geeft nul terug als de index buiten de limieten valt.

Als de verrekening 77 in plaats van 7 zou zijn geweest, dan zou de if-afrekening zijn overgeslagen.

Wat is het probleem?

Het zou veel gemakkelijker zijn om een Int-index voor snaren te gebruiken. De reden dat je voor elke string een nieuwe String.index moet maken is omdat de karakters in Swift niet allemaal even lang zijn onder de motorkap. Een enkel Swift-karakter kan bestaan uit één, twee of zelfs meer Unicode-codepunten. Daarom moet elke unieke string de indexen van zijn karakters berekenen.

Het is mogelijk om deze complexiteit te verbergen achter een Int-index extensie, maar ik aarzel om dat te doen. Het is goed om herinnerd te worden aan wat er werkelijk gebeurt.

Een nuttige Extension

De volgende Extenson moet worden toegevoegd onder uw klasse in de code. Deze uitbreiding biedt u de mogelijkheid om de index van een hele string binnen een string te bepalen. In mijn voorbeeld “grond”.

String operaties worden dus aangepakt via indices en ranges. De index is dus geen eenvoudige gehele variabele.

Dieser Block enthält unerwarteten oder ungültigen Inhalt.LösenZu HTML umwandeln

extension StringProtocol {
    func index(of string: S, options: String.CompareOptions = []) -&gt; Index? {
        range(of: string, options: options)?.lowerBound
    }
    func endIndex(of string: S, options: String.CompareOptions = []) -&gt; Index? {
        range(of: string, options: options)?.upperBound
    }
    func indices(of string: S, options: String.CompareOptions = []) -&gt; [Index] {
        var indices: [Index] = []
        var startIndex = self.startIndex
        while startIndex &lt; endIndex,
            let range = self[startIndex...]
                .range(of: string, options: options) {
                indices.append(range.lowerBound)
                startIndex = range.lowerBound &lt; range.upperBound ? range.upperBound :
                    index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
        }
        return indices
    }
    func ranges(of string: S, options: String.CompareOptions = []) -&gt; [Range] {
        var result: [Range] = []
        var startIndex = self.startIndex
        while startIndex &lt; endIndex,
            let range = self[startIndex...]
                .range(of: string, options: options) {
                result.append(range)
                startIndex = range.lowerBound &lt; range.upperBound ? range.upperBound :
                    index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
        }
        return result
    }
}

Over de auteur

Tobias Stephan administrator

Geef een reactie