Overriding Swift String’s Subscript Operator

UPDATE: The extension below always felt a bit dirty. There had to be a reason for the guardians of Swift not to provide simple access to characters via an integer subscript. In doing some research, I have found that I committed a terrible sin:

[As] simple as this code looks, it’s horribly inefficient. Every time s is accessed with an integer, an O(n) function to advance its starting index is run. Running a linear loop inside another linear loop means this for loop is accidentally O(n²) — as the length of the string increases, the time this loop takes increases quadratically.

Please forgive me.


With Swift 4, strings are once again a collection of characters. Maybe it’s my C++ upbringing, but an array of characters just feel right. Unfortunately, referencing a specific character in a Swift string isn’t as easy as using the subscript operator for an array. Instead of passing an integer into square brackets, iterating through the characters of a string requires the use of String.index. Simply writing myString[0] won’t work, we have to write:

let index = self.index(self.startIndex, offsetBy: (0))
mySelf[index]

I never remember this. Again, maybe it’s my C++ traumatized brain, but it just doesn’t sit right. So I made the equivalent of programatic comfort food with this little extension, overriding String’s subscript operator to accept a plain old Int:

extension String {
    subscript(i: Int) -> String {
        get {
            let index = self.index(self.startIndex, offsetBy: (i))
            return String(self[index])
        }
    }
}

And with that, myString[i] works and I don’t have to think too hard next time I reference a character.