[英]Getting “String.Index” while enumerating swift string
目前,我們迭代字符串如下:
let greeting = "Hello"
for (intIndex, char) in greeting.enumerated() {
let currentIndex = greeting.index(greeting.startIndex, offsetBy: intIndex)
let indexAfterCurrentIndex = greeting.index(after: currentIndex)
print(greeting[indexAfterCurrentIndex...])
}
我覺得用下面的代碼寫是多余的。
let currentIndex = greeting.index(greeting.startIndex, offsetBy: intIndex)
還有其他方法可以在迭代時直接獲取“ String.Index”嗎?
像這樣
let greeting = "Hello"
for (stringIndex, char) in greeting.enumeratedXXX() {
let indexAfterCurrentIndex = greeting.index(after: stringIndex)
print(greeting[indexAfterCurrentIndex...])
}
沒有內置功能。 您可以將其包裝在一個自定義的迭代器中,但是然后您只能將相同類型的計算封裝在不同的位置,所以這不是一個答案:)
但是,您可以提高當前代碼的性能:
greeting.index(greeting.startIndex, offsetBy: intIndex)
startIndex
到結果索引的索引。 index(_:offsetBy:)
的索引計算實際上只是另一個循環本身,其中每個索引+1
。 沒有O(1)
方式可以“計算”索引; 通過O(n)
的循環找到它 因此,您自己的外部循環與O(n)
成線性關系,共進行n
次迭代,每個字符一個。
然后使用內部循環計算索引意味着有1+2+3+4+5+6+...n = (n^2 + n)/2
次迭代,其中n
是intIndex
。
這意味着該算法具有*免除*回旋的復雜度O(n + n^2)
。 二次部分是有問題的!
您可以將復雜度降低到每個迭代2個操作,即O(2n)
。 只需將先前計算的索引保留在內存中,然后自己+1,就可以避免重新編寫代碼。
這是代碼:
let greeting = "Hello"
var index = greeting.startIndex
for char in greeting {
let indexAfterCurrentIndex = greeting.index(after: index)
print(greeting[indexAfterCurrentIndex...])
index = indexAfterCurrentIndex
}
仍然不是一個簡單的內置解決方案,但是您可以包裝這種更有效的算法,然后就可以使用!
extension String {
func forEachCharacterWithIndex(iterator: (String.Index, Character) -> Void) {
var currIndex = self.startIndex
for char in self {
iterator(currIndex, char)
currIndex = self.index(after: currIndex)
}
}
}
let greeting = "Hello"
greeting.forEachCharacterWithIndex { (index, char) in
let indexAfterCurrentIndex = greeting.index(after: index)
print(greeting[indexAfterCurrentIndex...])
}
如果需要字符串索引,則可以枚舉greeting.indices
:
let greeting = "Hello"
for index in greeting.indices {
// ...
}
如果需要每個字符及其索引,則可以並行枚舉字符串和索引:
let greeting = "Hello"
for (char, currentIndex) in zip(greeting, greeting.indices) {
let indexAfterCurrentIndex = greeting.index(after: currentIndex)
print(char, "-", greeting[indexAfterCurrentIndex...])
}
輸出:
H - ello e - llo l - lo l - o o -
一個更簡單的變體是
let greeting = "Hello"
for (char, nextIndex) in zip(greeting, greeting.indices.dropFirst()) {
print(char, "-", greeting[nextIndex...])
}
僅在沒有最后一個字符/索引對的情況下產生幾乎相同的結果:
H - ello e - llo l - lo l - o
為什么不將currentIndex增加1?
let greeting = "Hello"
for (stringIndex, char) in greeting.enumerated() {
let currentIndex = stringIndex
let nextIndex = currentIndex + 1
print(nextIndex)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.