【发布时间】:2018-01-26 09:40:42
【问题描述】:
如何在 Kotlin 中修改循环变量?
对于我的特殊情况,我有一个 for 循环,在该循环中,对于某些条件,我想跳过下一次迭代:
for(i in 0..n) {
// ...
if(someCond) {
i++ // Skip the next iteration
}
}
但是,当我尝试这个时,我被告知“无法重新分配 val”。
【问题讨论】:
如何在 Kotlin 中修改循环变量?
对于我的特殊情况,我有一个 for 循环,在该循环中,对于某些条件,我想跳过下一次迭代:
for(i in 0..n) {
// ...
if(someCond) {
i++ // Skip the next iteration
}
}
但是,当我尝试这个时,我被告知“无法重新分配 val”。
【问题讨论】:
你不能改变当前元素,你需要使用 while 循环来代替:
var i = 0
while (i <= n) {
// do something
if (someCond) {
i++ // Skip the next iteration
}
i++
}
你想做什么?有可能有更惯用的方法来做到这一点。
如果您可以重构此逻辑以跳过当前迭代,为什么不使用continue:
for (i in 0..n) {
if (someCond) {
continue
}
// ...
}
旁注:.. 范围包括在内,因此循环例如n 的大小列表,您通常需要 0..(n - 1),使用 until 更简单:0 until n。
在您的具体情况下,您可以使用windowed(Kotlin 1.2):
list.asSequence().filter { someCond }.windowed(2, 1, false).forEach {
val (first, second) = it
// ...
}
asSequence 会将列表转换为Sequence,从而消除filter 和windowed 创建新List 的开销(因为它们现在都将返回Sequences)。
如果您希望下一对不包含前一对的最后一个元素,请改用windowed(2, 2, false)。
【讨论】:
看起来您真正想做的是在列表上迭代大小为 2 的滑动窗口。如果您使用的是 kotlin 1.2 或更高版本,则可以使用 List.windowed() 库函数。
例如,要考虑每对相邻元素,但丢弃其中第二个为负数的元素,您会这样做:
val list = listOf(1, 2, 3, -4, -5, 6)
list.windowed(2,1).filter { it[1] > 0 }.apply(::println)
会打印出来的
[[1, 2], [2, 3], [-5, 6]]
跳过了 [3, -4] 和 [-4, -5] 对
【讨论】:
虽然很多人描述了这个问题并提出了一个我认为不适合初学者的高级方法或运算符的解决方案。 我对代码进行了修复,以便您可以轻松理解它,它只是使用 while 循环而不是 for 循环。如果您能理解并发现它有用,请考虑接受答案
fun main(args:Array<String>){
var alphabet = mutableListOf(
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
)
var key = "keyword"
println(key)
for (i in key.indices)
{
var j = 0
while (j < alphabet.size) {
if (key[i] == alphabet[j]){
alphabet.removeAt(j) // 1. this line have error
} else j++
}
}
print(alphabet)
}
【讨论】:
请试试这个方法,
for ((position, item) in list.withIndex()){
}
在这里你会得到位置和对象。
【讨论】: