[英]Getting “String.Index” while enumerating swift string
Currently we iterate string as below: 目前,我们迭代字符串如下:
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...])
}
I feel writing below code is redundant. 我觉得用下面的代码写是多余的。
let currentIndex = greeting.index(greeting.startIndex, offsetBy: intIndex)
Is there other way to get directly "String.Index" while iterating?
还有其他方法可以在迭代时直接获取“ String.Index”吗?
Something like this 像这样
let greeting = "Hello"
for (stringIndex, char) in greeting.enumeratedXXX() {
let indexAfterCurrentIndex = greeting.index(after: stringIndex)
print(greeting[indexAfterCurrentIndex...])
}
There is no built-in functionality for this. 没有内置功能。 You could wrap this in a custom iterator, but then you only encapsulate the same kind of computation in a different place, so that's not an answer :)
您可以将其包装在一个自定义的迭代器中,但是然后您只能将相同类型的计算封装在不同的位置,所以这不是一个答案:)
However, you can improve performance of your current code: 但是,您可以提高当前代码的性能:
greeting.index(greeting.startIndex, offsetBy: intIndex)
startIndex
to the resulting index for every loop iteration. startIndex
到结果索引的索引。 index(_:offsetBy:)
is really just another loop itself, where it +1
s each index. index(_:offsetBy:)
的索引计算实际上只是另一个循环本身,其中每个索引+1
。 There's no O(1)
way to "compute" the index; O(1)
方式可以“计算”索引; it is found out by a loop in O(n)
O(n)
的循环找到它 So your own outer loop is linear with O(n)
for n
iterations, one for every character. 因此,您自己的外部循环与
O(n)
成线性关系,共进行n
次迭代,每个字符一个。
Then computing the index with an inner loop means there are 1+2+3+4+5+6+...n = (n^2 + n)/2
iterations, where n
is the intIndex
in this case. 然后使用内部循环计算索引意味着有
1+2+3+4+5+6+...n = (n^2 + n)/2
次迭代,其中n
是intIndex
。
That means the algorithm has a complexity of *handwaiving* roundabout O(n + n^2)
. 这意味着该算法具有*免除*回旋的复杂度
O(n + n^2)
。 The quadratic part is problematic! 二次部分是有问题的!
You can get the complexity down to 2 operations per iteration, or O(2n)
. 您可以将复杂度降低到每个迭代2个操作,即
O(2n)
。 Just keep the previously computed index in memory and +1 yourself, avoiding a recomputation from scratch. 只需将先前计算的索引保留在内存中,然后自己+1,就可以避免重新编写代码。
Here's the code: 这是代码:
let greeting = "Hello"
var index = greeting.startIndex
for char in greeting {
let indexAfterCurrentIndex = greeting.index(after: index)
print(greeting[indexAfterCurrentIndex...])
index = indexAfterCurrentIndex
}
Still not a simple and built-in solution, but you can just as well wrap this more efficient algorithm and off you go! 仍然不是一个简单的内置解决方案,但是您可以包装这种更有效的算法,然后就可以使用!
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...])
}
If you need the string indices then you can enumerate greeting.indices
: 如果需要字符串索引,则可以枚举
greeting.indices
:
let greeting = "Hello"
for index in greeting.indices {
// ...
}
If you need each character together with its index then you can enumerate the string and the indices in parallel: 如果需要每个字符及其索引,则可以并行枚举字符串和索引:
let greeting = "Hello"
for (char, currentIndex) in zip(greeting, greeting.indices) {
let indexAfterCurrentIndex = greeting.index(after: currentIndex)
print(char, "-", greeting[indexAfterCurrentIndex...])
}
Output: 输出:
H - ello e - llo l - lo l - o o -
A simpler variant would be 一个更简单的变体是
let greeting = "Hello"
for (char, nextIndex) in zip(greeting, greeting.indices.dropFirst()) {
print(char, "-", greeting[nextIndex...])
}
which produces almost the same result, only without the last character/index pair: 仅在没有最后一个字符/索引对的情况下产生几乎相同的结果:
H - ello e - llo l - lo l - o
Why not increment the currentIndex by 1 ? 为什么不将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.