AnyIndex in Swift 6.x

I have been trying to wrap my head around AnyIndex.
However, every example I've found (including some AI-generated ones) seems to fail.
Here is an example:

let str = "Hello, World!"

// Using AnyIndex with a String
let start = AnyIndex(str.startIndex)
let end = AnyIndex(str.endIndex)

// Iterate through the string using AnyIndex
var idx = start
while idx != end {
    print(str[idx], terminator: " ")
    idx = AnyIndex(str.index(after: idx))
}

// Output: H e l l o ,   W o r l d !

Swift really doesn't like "[idx]"
What's wrong here?
FWIW, I wanted to use this to get String indices; however, I have other examples that fail on Int arrays.
Thanks

My understanding is that AnyIndex is used solely for AnyCollection and its variants. String can only take String.Index instances. Same for other bona fide collection types.

In the example above, if you remove all of the AnyIndex inits, I believe it will work as you intend it to.

3 Likes

My apologies if I misunderstood your question, but would indirect indexing work for you?

let s = "A πŸ‡¦πŸ‡« to Z πŸ‡ΏπŸ‡Ό flags!"
let w = StringWrapper (s)
print (w.value.count, "characters:", w)
for i in 0..<w.value.count {
    let c = w [i]
    print ("\t", i, c)
}
17 characters: A πŸ‡¦πŸ‡« to Z πŸ‡ΏπŸ‡Ό flags!
	 0 A
	 1  
	 2 πŸ‡¦πŸ‡«
	 3  
	 4 t
	 5 o
	 6  
	 7 Z
	 8  
	 9 πŸ‡ΏπŸ‡Ό
	 10  
	 11 f
	 12 l
	 13 a
	 14 g
	 15 s
	 16 !
Details
// StringWrapper.swift

struct StringWrapper {
    let value: String
    private var indexStore: [String.Index]
    
    init (_ value: String) {
        self.value = value
        self.indexStore = []
        var i = self.value.startIndex
        while i != self.value.endIndex {
            self.indexStore.append (i)
            i = self.value.index (after: i)
        }
    }
}

extension StringWrapper {
    subscript (index: Int) -> Character {
        assert (index >= 0)
        assert (index < indexStore.count)
        return value [indexStore [index]]
    }
}
//
//  Driver.swift

@main
enum Driver {
    static func main () async {
        do {
            let s = "A πŸ‡¦πŸ‡« to Z πŸ‡ΏπŸ‡Ό flags!"
            let w = StringWrapper (s)
            print (w.value.count, "characters:", w)
            for i in 0..<w.value.count {
                let c = w [I]
                print ("\t", i, c)
            }
        }
    }
}