Swift String.Index 与将字符串转换为数组
Swift String.Index vs transforming the String to an Array
在 swift 文档中,他们说他们使用 String.Index 来索引字符串,因为不同的字符可能占用不同的内存量。
但我看到很多人将字符串转换为数组 var a = Array(s)
这样他们就可以通过 int 索引而不是 String.Index (这绝对更容易)
所以我想自己测试是否所有unicode字符都完全相同:
let cafeA = "caf\u{E9}" // eAcute
let cafeB = "caf\u{65}\u{301}" // combinedEAcute
let arrayCafeA = Array(cafeA)
let arrayCafeB = Array(cafeB)
print("\(cafeA) is \(cafeA.count) character \(arrayCafeA.count)")
print("\(cafeB) is \(cafeB.count) character \(arrayCafeB.count)")
print(cafeA == cafeB)
print("- A scalar")
for scalar in cafeA.unicodeScalars {
print(scalar.value)
}
print("- B scalar")
for scalar in cafeB.unicodeScalars {
print(scalar.value)
}
这是输出:
café is 4 character 4
café is 4 character 4
true
- A scalar
99
97
102
233
- B scalar
99
97
102
101
769
果然,正如文档中提到的,字符串只是一个字符数组,然后字素簇在字符对象中向下,那么他们为什么不通过 int 对其进行索引呢? creating/using String.Index 实际上有什么意义?
在字符串中,字节表示是打包的,因此如果不从头遍历整个字符串,就无法知道字符边界在哪里。
当转换为数组时,这是一次遍历,结果是一个在内存中等距间隔的字符数组,这就是允许通过 Int
索引进行恒定时间下标的原因。重要的是,数组被保留下来,所以可以在同一个数组上完成许多下标操作,只需要遍历一次字符串的字节,用于初始解包。
可以使用下标扩展 String,下标通过 Int
对它进行索引,您会看到它经常出现在 SO 上,但这是不明智的。标准库程序员本可以添加它,但他们故意选择不这样做,因为它掩盖了每个索引操作都需要单独遍历字符串字节的事实,即 O(string.count)
。突然间,像这样无害的代码:
for i in string.indices {
print(string[i]) // Looks O(1), but is actually O(string.count)!
}
变成二次方。
在 swift 文档中,他们说他们使用 String.Index 来索引字符串,因为不同的字符可能占用不同的内存量。
但我看到很多人将字符串转换为数组 var a = Array(s)
这样他们就可以通过 int 索引而不是 String.Index (这绝对更容易)
所以我想自己测试是否所有unicode字符都完全相同:
let cafeA = "caf\u{E9}" // eAcute
let cafeB = "caf\u{65}\u{301}" // combinedEAcute
let arrayCafeA = Array(cafeA)
let arrayCafeB = Array(cafeB)
print("\(cafeA) is \(cafeA.count) character \(arrayCafeA.count)")
print("\(cafeB) is \(cafeB.count) character \(arrayCafeB.count)")
print(cafeA == cafeB)
print("- A scalar")
for scalar in cafeA.unicodeScalars {
print(scalar.value)
}
print("- B scalar")
for scalar in cafeB.unicodeScalars {
print(scalar.value)
}
这是输出:
café is 4 character 4
café is 4 character 4
true
- A scalar
99
97
102
233
- B scalar
99
97
102
101
769
果然,正如文档中提到的,字符串只是一个字符数组,然后字素簇在字符对象中向下,那么他们为什么不通过 int 对其进行索引呢? creating/using String.Index 实际上有什么意义?
在字符串中,字节表示是打包的,因此如果不从头遍历整个字符串,就无法知道字符边界在哪里。
当转换为数组时,这是一次遍历,结果是一个在内存中等距间隔的字符数组,这就是允许通过 Int
索引进行恒定时间下标的原因。重要的是,数组被保留下来,所以可以在同一个数组上完成许多下标操作,只需要遍历一次字符串的字节,用于初始解包。
可以使用下标扩展 String,下标通过 Int
对它进行索引,您会看到它经常出现在 SO 上,但这是不明智的。标准库程序员本可以添加它,但他们故意选择不这样做,因为它掩盖了每个索引操作都需要单独遍历字符串字节的事实,即 O(string.count)
。突然间,像这样无害的代码:
for i in string.indices {
print(string[i]) // Looks O(1), but is actually O(string.count)!
}
变成二次方。