String indices

Hi, I am trying to understand String indices exactly. Seems like that example does not work correctly as it prints this:

Screenshot 2020-11-22 at 16.28.48

Would anyone be so kind and clarify it for me? Thank You

What would you expect it to print?

thought its gonna print the letter before the last one. How could I do that instead?

print(string[indexLast])
1 Like

Swifts String does not work as many people expect:
"Unicode"[2] == "i"
Is not even allowed by the compiler (without libraries beyond the stdlib), because String uses a special index which is not a simple Int.
It's not hard to add such a subscript, though.

Oh, wait, that looks like a different issue :slight_smile:

No, that wouldn't be an index; what you want is string[indexLast].

Edit: No, actually you want to use the index before indexLast ;-)

1 Like

what about printing some middle letter?

Strings are hard — but to be fair, many other languages with a model that is easier to work with can produce incorrect results ;-)

You can (should ;-) use the index manipulation methods to get arbitrary elements.

For convenience, I suggest to create extension methods for String (actually, I would use the Collection protocols). That way, you don't have to repeat the string.-part that often.

1 Like

The trick is in identifying that string.index return back a type which is not integer, it is String.Index type

let string = "twojkiar"

//You are getting type back as String.index and not integer

let indexLast = string.index(before: string.endIndex)

type(of: indexLast)

print (string[indexLast])

Now, string.endIndex is one past the last character in the string so before endIndex gives you the last index

If you want to manipulate at want to get Character at a given string index then you can do so by doing something like:

string [string.index(string.startIndex, offsetBy: (string.count/2))]

offset as the name suggest is how much you want to move in either direction of starting point, we start at startIndex so we can go only positive direction

1 Like

Your indexLast is the position of the last character in your string, because endIndex is right after the last character. Here is the documentation of endIndex.

All you need to do is offset the index by one more, and print the character at the index instead of the index itself:

let string = "twojkiar"
let indexOfA = string.index(string.endIndex, offsetBy: -2)
print(string[indexOfA])

Here is the documentation of index(_:offsetBy:).

1 Like

To print the last element of the string use:

print(string[indexLast])

Your original expression printed out "indexLast" as an object in and of itself, not the part of "string" it referred to.

BTW, the String type is a bidirectional collection. This means that its index-pack type, i.e. String.Indices, is also a bidirectional collection. That means you can simply get the last index value by:

let indexLast = string.indices.last!

Of course, looking at that pattern, you can get the last element of the string similarly:

print(string.last!)

Again, this only works when the collection type conforms to BidirectionalCollection, and you have to test that .last isn't nil (or assure yourself that it won't be nil under your circumstances, and accept the consequences if you're wrong).

1 Like

If you really need to consider a string like a collection of characters, and randomly access arbitrary parts in the middle, you could convert your String to a randomly accessible collection (like e.g an Array) of Character elements, and access its elements through an Int index:

let string = ... // some string from somewhere
let chars = Array(string)

print(chars[chars.count/2])
print(chars.last)
print(chars[...])

However, except for some toy examples that often come up in coding tutorials, this kind of use case is pretty uncommon. You most likely want to walk (iterate through) the string, or use indices that are the result of some calculation based on actual string parsing and calculations.

4 Likes
Terms of Service

Privacy Policy

Cookie Policy