String indices in Swift 2

5.5k views Asked by At

I decided to learn Swift and I decided to start with Swift 2 right away.

So here is a very basic example that's similar to one of the examples from Apple's own e-book about Swift

let greeting = "Guten Tag"

for index in indices(greeting) {
    print(greeting[index])
}

I tried this in the playground of Xcode 7 and I received the following error

Cannot invoke 'indices' with an argument list of type '(String)'

I also tried the same thing with Xcode 6 (which is Swift 1.2 AFAIK) and it worked as expected.

Now, my question is: Is this

  1. An error in Xcode 7, it's still a beta release after all, or
  2. Something that just doesn't work anymore with Swift 2 and the e-book just isn't fully updated yet?

Also: If the answer is "2", how would you replace indices(String) in Swift 2?

3

There are 3 answers

2
Eric Aya On BEST ANSWER

In a Playground, if you go to menu View > Debug Area > Show debug area, you can see the full error in the console:

/var/folders/2q/1tmskxd92m94__097w5kgxbr0000gn/T/./lldb/94138/playground29.swift:5:14: error: 'indices' is unavailable: access the 'indices' property on the collection for index in indices(greeting)

Also, Strings do not conform to SequenceTypes anymore, but you can access their elements by calling characters.

So the solution for Swift 2 is to do it like this:

let greeting = "Guten Tag"

for index in greeting.characters.indices {
    print(greeting[index])
}

Result:

G
u
t
e
n

T
a
g

Of course, I assume your example is just to test indices, but otherwise you could just do:

for letter in greeting.characters {
    print(letter)
}
0
Narendra G On

Here is the code that you looking:

var middleName :String? = "some thing"
for index in (middleName?.characters.indices)! {
// do some thing with index
}
0
Daniel On

Just for completion, I have found a very simple way to get characters and substrings out of strings (this is not my code, but I can't remember where I got it from):

include this String extension in your project:

extension String {

    subscript (i: Int) -> Character {
        return self[self.startIndex.advancedBy(i)]
    }

    subscript (i: Int) -> String {
        return String(self[i] as Character)
    }

    subscript (r: Range<Int>) -> String {
        return substringWithRange(Range(start: startIndex.advancedBy(r.startIndex), end: startIndex.advancedBy(r.endIndex)))
    }
}

this will enable you to do:

print("myTest"[3]) //the result is "e"
print("myTest"[1...3]) //the result is "yTe"