更改Kotlin中的循环索引

Kri*_*ket 6 loops for-loop kotlin

如何在Kotlin中修改循环变量?

对于我的特定情况,我有一个for循环,在某些条件下,我想跳过下一次迭代:

for(i in 0..n) {
  // ...
  if(someCond) {
    i++ // Skip the next iteration
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试这个时,我被告知"val不能被重新分配".

Moi*_*ira 12

你不能改变当前元素,你需要使用一个while循环:

var i = 0
while (i <= n) {
    // do something        

    if (someCond) {
        i++ // Skip the next iteration
    }

    i++
}
Run Code Online (Sandbox Code Playgroud)

你想做什么?有可能有更惯用的方法来做到这一点.

如果您可以重构此逻辑以跳过当前迭代,为什么不使用continue:

for (i in 0..n) {
    if (someCond) {
        continue
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

旁注:..范围是包含的,因此循环通过例如n您通常需要的大小列表,0..(n - 1)更简单地完成until:0 until n.


编辑:关于你所说的,使用step应该工作:

for (i in 0 until n step 2) {
    val first = list[i]
    val second = list[i + 1]
    if (someCond) continue
    // ...
}
Run Code Online (Sandbox Code Playgroud)

(这也将确保i + 1在范围内)

编辑2:尝试windowed(Kotlin 1.2):

list.asSequence().filter { someCond }.windowed(2, 1, false).forEach { 
    val (first, second) = it
    // ...
}
Run Code Online (Sandbox Code Playgroud)

asSequence将列表转换为a Sequence,删除开销filterwindowed创建新的List(因为它们现在都返回Sequences).

如果您希望下一对不包含前一对的最后一个元素,请windowed(2, 2, false)改用.

  • 我必须说,他们让事情变得不必要的复杂化。在我看来,这是 Kotlin 倒退而非进化的少数几个领域之一。 (2认同)