我该如何在 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
的开销(因为它们现在都返回Sequence
)。
如果您希望下一对不包括前一对的最后一个元素,请改用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]]
虽然很多人用高级的方法或运算符描述问题并提出了解决方案,但我认为这对初学者来说并不合适。我在代码中应用了一个修复程序,以便您可以轻松理解它,并且仅使用 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()){
}
在这里,您将获得位置和对象。
windowed
或其他Iterable
内置函数,而不是直接使用索引进行操作。但总是有一些不幸的情况,你最终还是需要某种丑陋的解决方案。 - Salem