I have an extension here of the String class in Swift that returns the index of the first letter of a given substring.
Can anybody please help me make it so it will
Here are 2 functions. One returns [Range, the other returns [Range. If you don't need the former, you can make it private. I've designed it to mimic the range(of:options:range:locale:) method, so it supports all the same features.
import Foundation
extension String {
public func allRanges(
of aString: String,
options: String.CompareOptions = [],
range: Range? = nil,
locale: Locale? = nil
) -> [Range] {
// the slice within which to search
let slice = (range == nil) ? self[...] : self[range!]
var previousEnd = s.startIndex
var ranges = [Range]()
while let r = slice.range(
of: aString, options: options,
range: previousEnd ..< s.endIndex,
locale: locale
) {
if previousEnd != self.endIndex { // don't increment past the end
previousEnd = self.index(after: r.lowerBound)
}
ranges.append(r)
}
return ranges
}
public func allRanges(
of aString: String,
options: String.CompareOptions = [],
range: Range? = nil,
locale: Locale? = nil
) -> [Range] {
return allRanges(of: aString, options: options, range: range, locale: locale)
.map(indexRangeToIntRange)
}
private func indexRangeToIntRange(_ range: Range) -> Range {
return indexToInt(range.lowerBound) ..< indexToInt(range.upperBound)
}
private func indexToInt(_ index: String.Index) -> Int {
return self.distance(from: self.startIndex, to: index)
}
}
let s = "abc abc abc abc abc"
print(s.allRanges(of: "abc") as [Range])
print()
print(s.allRanges(of: "abc") as [Range])