Marcus Rossel
Marcus Rossel

Reputation: 3268

How to access `String`s at a given `Index` concisely?

In Swift 3 SE-0065 changed the indexing model for Collections, wherein responsibility for index traversal is moved from the index to the collection itself. For example, instead of writing i.successor(), onehas to write c.index(after: i).

What this means in terms of accessing Strings at a certain index, is that instead of writing this:

let aStringName = "Bar Baz"
aStringName[aStringName.startIndex.advancedBy(3)]

...we now have to write this:

aStringName[aStringName.index(aStringName.startIndex, offsetBy: 3)]

This seems incredibly redundant, as aStringName is mentioned thrice. So my question is if there's any way to get around this (aside from writing an extension to String)?

Upvotes: 0

Views: 351

Answers (2)

Code Different
Code Different

Reputation: 93191

For future Googlers, I'm posting my String extension below. It allows you to access a string with Ints rather than the cumbersome Index:

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

    subscript(range: CountableRange<Int>) -> String {
        let startIndex = self.index(self.startIndex, offsetBy: range.lowerBound)
        let endIndex = self.index(startIndex, offsetBy: range.count)
        return self[startIndex..<endIndex]
    }

    subscript(range: CountableClosedRange<Int>) -> String {
        let startIndex = self.index(self.startIndex, offsetBy: range.lowerBound)
        let endIndex = self.index(startIndex, offsetBy: range.count)
        return self[startIndex...endIndex]
    }

    subscript(range: NSRange) -> String {
        let startIndex = self.index(self.startIndex, offsetBy: range.location)
        let endIndex = self.index(startIndex, offsetBy: range.length)
        return self[startIndex..<endIndex]
    }
}

let str = "Hello world"

print(str[0])                   // Get the first character
print(str[0..<5])               // Get characters 0 - 4, with a CountableRange
print(str[0...4])               // Get chacraters 0 - 4, with a ClosedCountableRange
print(str[NSMakeRange(0, 5)])   // For interacting with Foundation classes, such as NSRegularExpression

Upvotes: 5

Marcus Rossel
Marcus Rossel

Reputation: 3268

It seems there's no neat or concise way to do this without writing an extension. A version of such an extension could look like this:

extension String {
  subscript(offset offset: Int) -> Character {
    return self[index(startIndex, offsetBy: offset)]
  }
}

Upvotes: 0

Related Questions