Matt Gibson
Matt Gibson

Reputation: 38238

What's a good way to iterate backwards through the Characters of a String?

What's the most Swiftian way to iterate backwards through the Characters in a String? i.e. like for ch in str, only in reverse?

I think I must be missing something obvious, because the best I could come up with just now was:

    for var index = str.endIndex; 
            index != str.startIndex; 
            index = index.predecessor() {
        let ch = str[index.predecessor()]
        ...
    }

I realise "what's the best..." may be classed as subjective; I suppose what I'm really looking for is a terse yet readable way of doing this.

Edit: While reverse() works and is terse, it looks like this might be quite inefficient compared to the above, i.e. it seems like it's not actually iterating backwards, but creating a full reverse copy of the characters in the String. This would be much worse than my original if, say, you were looking for something that was usually a few characters from the end of a 10,000-character String. I'm therefore leaving this question open for a bit to attract other approaches.

Upvotes: 14

Views: 12713

Answers (5)

pNre
pNre

Reputation: 5376

The reversed function reverses a C: CollectionType and returns a ReversedCollection:

for char in "string".characters.reversed() {
  // ...
}

If you find that reversed pre-reverses the string, try:

for char in "string".characters.lazy.reversed() {
  // ...
}

lazy returns a lazily evaluated sequence (LazyBidirectionalCollection) then reversed() returns another LazyBidirectionalCollection that is visited in reverse.

Upvotes: 30

pbush25
pbush25

Reputation: 5248

As of December 2015 with Swift version 2.1, the proper way to do this is

for char in string.characters.reverse() {
    //loop backwards
}

String no longer conforms to SequenceType<T> but its character set does.

Upvotes: 5

Phil
Phil

Reputation: 1

this?

extension String {
    var reverse: String {
        var reverseStr = ""
        for character in self {
            reverseStr = String(character) + reverseStr
        }
        return reverseStr
    }
}

Upvotes: -3

Paul Tervit
Paul Tervit

Reputation: 11

Here is a code for reversing a string that doesn't use reverse(str)

  // Reverse String

func myReverse(str:String) -> String {

    var buffer = ""

    for character in str {

        buffer.insert(character, atIndex: buffer.startIndex)
    }

    return buffer
}

myReverse("Paul")  // gives “luaP”

Just a little experiment. For what its worth.

Ok, leant how to read the question....

Would this work Matt?

func ReverseIteration(str:String) {

    func myReverse(str:String) -> String {

        var buffer = ""

        for character in str {

            buffer.insert(character, atIndex: buffer.startIndex)
        }

        return buffer
    }

    // reverse string then iterate forward.

    var newStr = myReverse(str)

    for char in newStr {

        println(char)
        // do some  code here

    }

Upvotes: 1

Alexey Globchastyy
Alexey Globchastyy

Reputation: 2175

Not sure about efficiency, but I will suggest

for ch in reverse(str) {
    println(ch)
}

Upvotes: 4

Related Questions