Here is a simple function that replaces "Hello" in "Hello,My friend" with helloReplacement
and prints the character that is expected to be 'i'. To do so, the index that points to 'i' in the original string is calculated and adjusted accordingly after replacement. When helloReplacement
contains an emoji, the function doesn't work as expected.
Does anyone know the reason? I could not get my head around it. It seems after mutating a string, Index
obtained before mutation is not valid anymore. Is it true? If yes, what is happening under the hood that leads to this result?
/// Replace "Hello" with `helloReplacement` and print the character expected to be 'i'
func replaceHello(with helloReplacement: String) {
var str = "Hello,My friend"
let offset = helloReplacement.utf16.count - "Hello".utf16.count
let i_index = str.utf16.index(str.utf16.startIndex, offsetBy: 11)
let o_index = str.utf16.index(str.startIndex, offsetBy: 5)
str.replaceSubrange(str.startIndex ..< o_index, with: helloReplacement)
let i_new_index = str.utf16.index(i_index, offsetBy: offset)
print(str[i_new_index])
}
replaceHello(with: "Hi")
replaceHello(with: "๐๐ปโโ๏ธ")
replaceHello(with: "Goodbye")
replaceHello(with: "ุณูุงู
")
replaceHello(with: "๐")
/* Output:
i
,
i
y
f
*/
Tested on Swift4.2 and 5.1