Substring
In Swift 5.8 we can acquire a substring in many ways. Strings cannot be directly indexed by integers, but we can use ranges to take substrings.
With startIndex
and endIndex
, we access character offsets in strings. We use index()
to move past the start and end. With the resulting range, we get a substring.
This program takes a substring of a string
. We first create a range. We use the half-open range operator on the endIndex
of the "name" string
.
index()
on the string
and pass startIndex
and an offsetBy
int
to get the start of the range. We advance 4 chars.let name = "The Grapes of Wrath" // Get range based on the string index. let r = name.index(name.startIndex, offsetBy: 4)..<name.endIndex // Access substring from range. let result = name[r] print(result)Grapes of Wrath
This example is similar, but uses a different end. We isolate the middle substring "two" of our input string
. We use index()
to omit the first 4 and last 6 characters.
endIndex
of the string
. We move backwards 6 chars from the end of the string
.string
with the range. It equals "two."// This is the input string. let s = "one two three" // Get range 4 places from the start, and 6 from the end. let r = s.index(s.startIndex, offsetBy: 4)..<s.index(s.endIndex, offsetBy: -6) // Access the string by the range. let substring = s[r] print(substring)two
Sometimes we want to base a substring on the end of the string
. Here we call index()
to adjust the start index of the range by 6 chars.
string
.let value = "bird, lizard and fish" // Get range of all characters past the first 6. let range = value.index(value.startIndex, offsetBy: 6)..<value.endIndex // Access the substring. let substring = value[range] print(substring)lizard and fish
RemoveSubrange
This func
can be used to create substrings. We specify the range of the string
we want to remove. The string
is modified to have only the remaining characters.
string
. We pass a range to the removeSubrange
method.string
's startIndex
. It covers the start to six places past the start.var
keyword declare the string
"dotnetperls" here. The string
is modified by removeSubrange
.var name = "dotnetperls" // Remove the first 6 characters from this string. // ... We begin at startIndex. // ... We continue until startIndex advanced by 6 chars. name.removeSubrange(name.startIndex..<name.index(name.startIndex, offsetBy: 6)) print(name)perls
Substring
after char
This program introduces a secondWord
method. It searches for a space in the argument string
. It then returns the substring after that space character.
firstIndex()
method to search for a space in secondWord
. We then use "if let" to see if the space was found.string
's endIndex
.string
from a subscript. We must return the String()
with a special call.func secondWord(value: String) -> String { // Find index of space. if let space = value.firstIndex(of: " ") { // Return String. // ... Use "after" to avoid including the space. // Use String() to for Swift 4. return String(value[value.index(after: space)..<value.endIndex]) } return "" } // Test our func. print(secondWord(value: "orange cat")) print(secondWord(value: "black dog")) print(secondWord(value: "multicolored parrot"))cat dog parrot
Index
before, afterWe can use firstIndex()
and index()
to search for a character in a string
. With index()
we can get the index before or after another index.
string
. This shows how the index method changes its results based on its arguments.let colors = "blue,red,green" // Get character indexes. let indexE = colors.firstIndex(of: "e")! let indexComma = colors.firstIndex(of: ",")! // Get before and after indexes. let indexBeforeE = colors.index(before: indexE) let indexAfterE = colors.index(after: indexE) let indexBeforeComma = colors.index(before: indexComma) let indexAfterComma = colors.index(after: indexComma) // Get substrings based on ranges. print("IndexE: \(colors[indexE..<colors.endIndex])") print("IndexComma: \(colors[indexComma..<colors.endIndex])") print("IndexBeforeE: \(colors[indexBeforeE..<colors.endIndex])") print("IndexAfterE: \(colors[indexAfterE..<colors.endIndex])") print("IndexBeforeComma: \(colors[indexBeforeComma..<colors.endIndex])") print("IndexAfterComma: \(colors[indexAfterComma..<colors.endIndex])")IndexE: e,red,green IndexComma: ,red,green IndexBeforeE: ue,red,green IndexAfterE: ,red,green IndexBeforeComma: e,red,green IndexAfterComma: red,green
Single
char
, StartIndex
To access a character from a string
, we must use an index (not an Int
). Here we use startIndex
to get the first char
in the string "Puma."
let value = "Puma" // A string's chars can be accessed with startIndex or endIndex. let char = value[value.startIndex] print(char)P
Int
subscriptA string
cannot be indexed by an Int
. Characters in a string
may be different lengths. So we must access strings with ranges based on startIndex
and endIndex
.
let value = "lion" // A string cannot be accessed with Ints. var char = value[0]main.swift:3:12: 'subscript' is unavailable: cannot subscript String with an Int
String
errorIn Swift 4 and beyond we must return a String
with a special call. We cannot just return the result of a subscript directly.
func removeFirst2Chars(value: String) -> String { // We need to wrap this in a String call. return value[value.index(value.startIndex, offsetBy: 2)..<value.endIndex] } print(removeFirst2Chars(value: "xxy"))program.swift:3:9: error: subscripts returning String were obsoleted in Swift 4; explicitly construct a String from subscripted result
String
, fixHere is the special call to String()
to return a string
from a func
. The subscript expression is wrapped inside a String()
func
call.
func removeFirst2Chars(value: String) -> String { return String(value[value.index(value.startIndex, offsetBy: 2)..<value.endIndex]) } print(removeFirst2Chars(value: "xxy"))y
In Swift, strings must be accessed by ranges based on the startIndex
and endIndex
. This is because chars are not all the same size. Substrings become less intuitive.