Why is Swift String Manipulation like that
String Manipulation is notoriously tricky in Swift. Some common complaints:
- Three different datatypes: String, Substring, and Character.
- Cannot iterate String with Integer. We need to use a separate datatype called
String.Index
.
So a simple palindrome search goes from this in Python:
if string[i] != string[length - 1 - i]:
To this in Swift:
// ...
if String(string[String.Index(string.startIndex, offsetBy: i)]) != String(string[String.Index(string.endIndex, offsetBy: -i)]) // What is wrong with you?
// ...
See the perplexing syntax? However, there are several reasons why Swift Strings are designed this way.
-
Substrings. Swift Strings are value types copied when assigned or passed to a function. This can be good for stability but bad for efficiency, especially when working with large strings. Therefore we have the substring datatype, which does not create a new instance.
-
String.Index, Character. Swift Strings are Unicode-Correct, which means they can handle complex characters and Emoji; ever experienced where complex Emoji are 3-4 characters combined in length? These include words with "extended grapheme clusters", such as "รฉ", "๊น" and "๐ฎ๐ณ". Using Integer, their length will vary, but in String.Index they are all length 1. Apple's Example:
let cafe = "Cafe\u{301} du ๐"
print(cafe) // Prints "Cafรฉ du ๐"
print(cafe.count) // Prints "9"
print(Array(cafe)) // Prints ["C", "a", "f", "รฉ", " ", "d", "u", " ", "๐"]
It's always a compromise, one or the other.
The difference between ordinary and extraordinary is that little extra.
โ Jimmy Johnson (1943โ)