How to setup for each loop in Kotlin to avoid out of bounds exception

Viewed 91

In java I got this construction

for (let i = 0; i < x.length-1; I++

And here to avoid outOfBoundsException we are using x.length-1 but how to do the same thing in Kotlin? I got this code so far

x.forEachIndexed { index, _ ->
    output.add((x[index+1]-x[index])*10)
}

And it crashes on the last element when we call x[index+1] so I need to handle the last element somehow

Input list

var x = doubleArrayOf(0.0, 0.23, 0.46, 0.69, 0.92, 1.15, 1.38, 1.61)
2 Answers

For a classic Java for loop you got two options in Kotlin.

One would be something like this.

val x = listOf(1,2,3,4)

for (i in 0 .. x.lastIndex){
    // ...
}

Using .. you basically go from 0 up to ( and including) the number coresponding to the second item, in this case the last index of the list.( so from 0 <= i <= x.lastIndex)

The second option is using until

val x = listOf(1,2,3,4)

for (i in 0 until x.size){
    // ...
}

This is similar to the previous approach, except the fact that until is not inclusive with the last element.(so from 0 <= i < x.size ).

What you probably need is something like this

val x = listOf(1,2,3,4)

for (i in 0 .. x.lastIndex -1){
    // ...
}

or alternative, using until, like this

val x = listOf(1,2,3,4)

for (i in 0 until x.size-1){
    // ...
}

This should probably avoid the IndexOut of bounds error, since you go just until the second to last item index.

Feel free to ask more if something is not clear.

This is also a great read if you want to learn more about ranges. https://kotlinlang.org/docs/ranges.html#progression

You already have an answer, but this is another option. If you would use a normal list, you would have access to zipWithNext(), and then you don't need to worry about any index, and you can just do:

list.zipWithNext { current, next ->
    output.add((next - current)*10)
}

As mentioned by k314159, we can also do asList() to have direct access to zipWithNext and other list methods, without many drawbacks.

array.asList().zipWithNext { current, next ->
    output.add(next - current)
}
Related