1
let greeting = "Hello World"
greeting[greeting.startIndex]

This code will print first character of string "H"

let = "Hello World"
greeting.startIndex
greeting.endIndex

whats the difference? this thing don't do anything. Even i dont get error for

greeting.endIndex

of course I am not retrieving string value through subscript syntax but in the Substring topic I found

greeting.endIndex

it is print only

string.index

Ok let me explain why I am asking about string.index and greeting.endIndex

let greeting = "Hello_world!"
let index = greeting.index(of: "_") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"

This code is related to substring, I totally understand what is it doing and in second line of code there is Nil-Coalescing Operator and you know what is it for. But what if

let greeting = "Hello world!"
let index = greeting.index(of: "_") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello world"

If there is no "_" in string value means greeting.index(of: "_") is nil then it should be returns default value greeting.endIndex as Nil-Coalescing Operator does right. So why does greeting.endIndex returning `"Hello world!"

3 Answers3

1

In case you describe startIndex return position of the first character in a nonempty string and the endIndex return the position one greater than the last valid subscript argument.

Also in version 4 of the Swift. String is represented as Collection.

So when you do:

greeting[greeting.startIndex]

You ask greeting string to return element in the first position that is "H"

Oleg Gordiichuk
  • 15,240
  • 7
  • 60
  • 100
1

Your code does nothing. This code however

let greeting = "Hello"

print(greeting[greeting.startIndex]) // Prints 'H'
print(greeting[greeting.endIndex])

Causes a fatal error because greeting.endIndex actually "points" to just after the end of the String, so the last statement is an array bounds violation.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • @MartinR `greeting[greeting.endIndex]` also causes a fatal error when typed into a Playground – JeremyP Oct 27 '17 at 09:04
  • @MartinR `greeting.endIndex` in a Playground just says (effectively) this is a `String.Index` – JeremyP Oct 27 '17 at 09:06
  • 1
    Sure. I am just referring to *"Your code does nothing"*. In a Playground, the expression will be evaluated and the results printed to the output window. – Martin R Oct 27 '17 at 09:06
  • hey can you please tell me how to add linebrake while typing code in comments. so I can explain. –  Oct 27 '17 at 09:07
  • @Tanzz I've been on here for 6 years, have a rep of over 68k and I do not know how to put line breaks in code in comments :-) – JeremyP Oct 27 '17 at 09:08
  • 1
    @Tanzz: Put all relevant information into the question, not in comments. – Martin R Oct 27 '17 at 09:13
  • @Martin R hey i put all the information in question. Can you please check it again? I hope it will help to understand why i was confuse about `greeting.endIndex` –  Oct 27 '17 at 10:15
  • is `greeting.endIndex` used in that example like `prefix(_:)` method ? `prefix(_:)` Returns a subsequence, up to the specified maximum length, containing the initial elements of the collection.If the maximum length exceeds the number of elements in the collection, the result contains all the elements in the collection. –  Oct 27 '17 at 10:26
1

The startIndex is the start of the string. The endIndex is the end of the string. You can use these when building ranges or when creating new indexes as an offsetBy from one or both of these.

So, for example, if you want a Substring that excluded the first and last characters, you could set fromIndex to be startIndex plus 1 and toIndex to be endIndex less 1, yielding:

let string = "Hello World"
let fromIndex = string.index(string.startIndex, offsetBy: 1)
let toIndex = string.index(string.endIndex, offsetBy: -1)
let substring = string[fromIndex..<toIndex]                // "ello Worl"

You then ask:

If there is no "_" in string value means greeting.index(of: "_") is nil then it should be returns default value greeting.endIndex as Nil-Coalescing Operator does right. So why does greeting.endIndex returning `"Hello world!"

Make sure you don't conflate the string[index] syntax (which returns a Character) and the string[..<index] which returns a Substring from the startIndex up to index (i.e. "return Substring of everything up to index"):

let beginning = greeting[..<index]

This partially bound range is just short-hand for:

let beginning = greeting[greeting.startIndex..<index]

So, when you default index to the greeting.endIndex, that's like saying you want a substring that is, effectively, the whole string:

let beginning = greeting[greeting.startIndex..<greeting.endIndex]

So, that's why the syntax presented in your question, greeting[..<index], returns the whole string if _ was not found and it used endIndex.


As an aside, if you wanted different behavior, namely for it to return an empty substring if the _ is not found, you could do the following:

let index = greeting.index(of: "_") ?? greeting.startIndex
let beginning = greeting[..<index]

Or, if you think that's a little too cute, just adopt standard safe unwrapping patterns, e.g.:

guard let index = greeting.index(of: "_") else {
    // handle unfound _ here
}
let beginning = greeting[..<index]
Rob
  • 415,655
  • 72
  • 787
  • 1,044