How can I modify the loop variable in Kotlin?
For my particular case, I have a for-loop in which, for certain conditions, I want to skip the next iteration:
for(i in 0..n) {
// ...
if(someCond) {
i++ // Skip the next iteration
}
}
However, when I try this, I'm told that "val cannot be reassigned".
You can't mutate the current element, you would need to use a while
loop instead:
var i = 0
while (i <= n) {
// do something
if (someCond) {
i++ // Skip the next iteration
}
i++
}
What are you trying to do? There is a chance there is a more idiomatic way to do this.
If you could restructure this logic to skip the current iteration, why not use continue
:
for (i in 0..n) {
if (someCond) {
continue
}
// ...
}
Side note: ..
ranges are inclusive, so to loop through e.g. a list of size n
you usually need 0..(n - 1)
which is more simply done with until
: 0 until n
.
Edit: about what you've said, using step
should work:
for (i in 0 until n step 2) {
val first = list[i]
val second = list[i + 1]
if (someCond) continue
// ...
}
(this will also ensure that i + 1
is in range)
Edit 2: try windowed
(Kotlin 1.2):
list.asSequence().filter { someCond }.windowed(2, 1, false).forEach {
val (first, second) = it
// ...
}
asSequence
will convert the list into a Sequence
, removing the overhead of filter
and windowed
creating a new List
(as they will now both return Sequence
s).
If you want the next pair to not include the last element of the previous pair, use windowed(2, 2, false)
instead.
It looks like what you're really trying to do is iterate a sliding window of size 2 over a list. If you're using kotlin 1.2 or later, you might use the List.windowed()
library function.
For example, to consider each pair of adjacent elements, but discarding the ones where the second of the pair is negative, you would do:
val list = listOf(1, 2, 3, -4, -5, 6)
list.windowed(2,1).filter { it[1] > 0 }.apply(::println)
Which would print out
[[1, 2], [2, 3], [-5, 6]]
having skipped the pairs [3, -4] and [-4, -5]