Swift Language Strings and Characters String Iteration

Help us to keep this website almost Ad Free! It takes only 10 seconds of your time:
> Step 1: Go view our video on YouTube: EF Core Bulk Insert
> Step 2: And Like the video. BONUS: You can also share it!

Example

3.0
let string = "My fantastic string"
var index = string.startIndex

while index != string.endIndex {
    print(string[index])
    index = index.successor()
}

Note: endIndex is after the end of the string (i.e. string[string.endIndex] is an error, but string[string.startIndex] is fine). Also, in an empty string (""), string.startIndex == string.endIndex is true. Be sure to check for empty strings, since you cannot call startIndex.successor() on an empty string.

3.0

In Swift 3, String indexes no longer have successor(), predecessor(), advancedBy(_:), advancedBy(_:limit:), or distanceTo(_:).

Instead, those operations are moved to the collection, which is now responsible for incrementing and decrementing its indices.

Available methods are .index(after:), .index(before:) and .index(_:, offsetBy:).

let string = "My fantastic string"
var currentIndex = string.startIndex

while currentIndex != string.endIndex {
    print(string[currentIndex])
    currentIndex = string.index(after: currentIndex)
}

Note: we're using currentIndex as a variable name to avoid confusion with the .index method.

And, for example, if you want to go the other way:

3.0
var index:String.Index? = string.endIndex.predecessor()

while index != nil {
    print(string[index!])
    if index != string.startIndex {
        index = index.predecessor()
    }
    else {
        index = nil
    }
}

(Or you could just reverse the string first, but if you don't need to go all the way through the string you probably would prefer a method like this)

3.0
var currentIndex: String.Index? = string.index(before: string.endIndex)

while currentIndex != nil {
    print(string[currentIndex!])
    if currentIndex != string.startIndex {
        currentIndex = string.index(before: currentIndex!)
    }
    else {
        currentIndex = nil
    }
}

Note, Index is an object type, and not an Int. You cannot access a character of string as follows:

let string = "My string"
string[2] // can't do this
string.characters[2] // and also can't do this

But you can get a specific index as follows:

3.0
index = string.startIndex.advanceBy(2)
3.0
currentIndex = string.index(string.startIndex, offsetBy: 2)

And can go backwards like this:

3.0
index = string.endIndex.advancedBy(-2)
3.0
currentIndex = string.index(string.endIndex, offsetBy: -2)

If you might exceed the string's bounds, or you want to specify a limit you can use:

3.0
index = string.startIndex.advanceBy(20, limit: string.endIndex)
3.0
currentIndex = string.index(string.startIndex, offsetBy: 20, limitedBy: string.endIndex)

Alternatively one can just iterate through the characters in a string, but this might be less useful depending on the context:

for c in string.characters {
    print(c)
}


Got any Swift Language Question?