Reputation: 1071
I have strings and determine the ranges of indexes. I will need later for instance .last
.count
for these ranges. How should I initialise the range for string to be able to get functionality .last
.count
for these ranges (that is obvious in swift2 but not in swift3) ?
For example, I am often using the .count
for range of string in my code in swift2, like this
var str = "Hello, playground"
let myRange = str.rangeOfString("Hello")
let myCountOfRange = myRange.count
Now it is not possible to do this in swift3
var str = "Hello, playground"
let myRange = str.range(of: "Hello")
let myCountOfRange = myRange.count // type index does not conform to protocol strideable
Upvotes: 0
Views: 582
Reputation: 154731
In Swift3, to find the size of a range you can do:
var str = "Hello, playground"
let myRange = str.range(of: "Hello")
let myCountOfRange = str[myRange!].characters.count
I don't know if this is the best way, but it works.
Alternatively:
let myCountOfRange = str.distance(from: myRange!.lowerBound, to: myRange!.upperBound)
Both require access to the original collection (ie. string), and that apparently is a limitation of Swift 3. The new model for collections and indices is discussed here.
If you want to store the ranges in an array and call .count
and .last
on them, you can convert the Range<Index>
to a CountableRange<Int>
while you still have access to the collection:
var str = "Hello, playground"
let myRange = str.range(of: "Hello")!
let lb = str.distance(from: str.startIndex, to: myRange.lowerBound) as Int
let ub = str.distance(from: str.startIndex, to: myRange.upperBound) as Int
let newRange = lb..<ub
newRange.count // 5
newRange.last // 4
Upvotes: 2