So
for-in
and
.forEach()
do not work on
Range<String.Index>
and I can see why: it's because it needs the original string to move:
let s = "xxxxxxx12345yyyyy"
let a = s.index(s.startIndex, offsetBy: 7)
let b = s.index(s.endIndex, offsetBy: -5)
let r = a ..< b
// how to iterate through r?
// for-in and .forEach() do not work. I see why: because the original string is needed to move
//for i in r { // Protocol 'Sequence' requires that 'String.Index' conform to 'Strideable'
// print(i)
//r.forEach { // Referencing instance method 'forEach' on 'Range' requires that 'String.Index' conform to 'Strideable'
// print($0)
// this works, but it's clumsy
var i = a
while i < b {
print(s[i])
i = s.index(after: i)
// does something like this already exist?
struct StringIndexRangeIterator: Sequence, IteratorProtocol {
private let string: String
private var at: String.Index
private let end: String.Index
init(_ s: String, range: Range<String.Index>) {
string = s
at = range.lowerBound
end = range.upperBound
mutating func next() -> String.Index? {
if at >= end {
return nil
} else {
defer { at = string.index(after: at) }
return at
extension String {
func iterator(of range: Range<String.Index>) -> StringIndexRangeIterator {
StringIndexRangeIterator(self, range: range)
// now it's nice and easy to iterate
for i in s.iterator(of: r) {
print(s[i])
let a = s.index(s.startIndex, offsetBy: 7)
let b = s.index(s.endIndex, offsetBy: -5)
let r = s[a ..< b]
for each in r {
print(each)
let a = s.index(s.startIndex, offsetBy: 7)
let b = s.index(s.endIndex, offsetBy: -5)
let r = a ..< b
// or just s[r] if you don't need the index itself, as @masters3d said above.
for i in s.indices[r] {
print("index \(i) has char \(s[i]) ")
let a = s.index(s.startIndex, offsetBy: 7)
let b = s.index(s.endIndex, offsetBy: -5)
let r = a ..< b
// or just s[r] if you don't need the index itself
for i in s.indices[r] {
print("index \(i) has char \(s[i])...
I noticed that (with Xcode 12.5) this
extension Collection where Self.Index == Self.Indices.Index {
compiles without any warning, as implied by your statement, but this:
struct S<T: Collection> where T.Index == T.Indices.Index {
results in a warning
"Redundant same-type constraint `T.Index` == `T.Indices.Index`"
Why is this?