Galih indra
Galih indra

Reputation: 403

How to make reversed for loop with array index as a start/end point in Kotlin?

I tried to create a reversed loop. The simplest way to reverse a for loop is: for (i in start downTo end)

But what if I want to use an array as the start or end point?

Upvotes: 25

Views: 22066

Answers (6)

CoolMind
CoolMind

Reputation: 28783

list.reversed().forEachIndexed { index, data ->
    action(data)
}

Test:

val list = listOf("a", "b", "c", "d", "e")
list.reversed().forEachIndexed { index, data ->
    println("$index $data")
}
println("---")
list.withIndex().reversed().forEach {
    println("${it.index} ${it.value}")
}

0 e
1 d
2 c
3 b
4 a
---
4 e
3 d
2 c
1 b
0 a

Upvotes: 1

Renetik
Renetik

Reputation: 6373

For performance optimal implementation you can use this:

inline fun <T> Array<T>.forEachReverse(action: (T) -> Unit) {
    var index = lastIndex
    while (index >= 0) {
        action(this[index])
        index--
    }
}

It does not create another instance and still uses classical forEach syntax, so you can drop in replace and also is inlined.

For list the same:

inline fun <T> List<T>.forEachReverse(action: (T) -> Unit) {
    var index = size - 1
    while (index >= 0) {
        action(this[index])
        index--
    }
}

Upvotes: 0

A very clean way in kotlin:

for (i in array.indices.reversed()) {
    println(array[i])
}

Upvotes: 4

jack_the_beast
jack_the_beast

Reputation: 1971

Just leaving it here in case someone needs it

I created an extension function:

public inline fun <T> Collection<T>.forEachIndexedReversed(action: (index: Int, T) -> Unit): Unit {
    var index = this.size-1
    for (item in this.reversed()) action(index--, item)
}

Upvotes: 1

DVarga
DVarga

Reputation: 21799

Additionally to the first answer from zsmb13, some other variants.

Using IntProgression.reversed:

for (i in (0..array.lastIndex).reversed())
    println("On index $i the value is ${array[i]}")

or using withIndex() together with reversed()

array.withIndex()
        .reversed()
        .forEach{ println("On index ${it.index} the value is ${it.value}")}

or the same using a for loop:

for (elem in array.withIndex().reversed())
    println("On index ${elem.index} the value is ${elem.value}")

or if the index is not needed

for (value in array.reversed())
    println(value)

Upvotes: 20

zsmb13
zsmb13

Reputation: 89548

You can loop from the last index calculated by taking size - 1 to 0 like so:

for (i in array.size - 1 downTo 0) {
    println(array[i])
}

Even simpler, using the lastIndex extension property:

for (i in array.lastIndex downTo 0) {
    println(array[i])
}

Or you could take the indices range and reverse it:

for (i in array.indices.reversed()) {
    println(array[i])
}

Upvotes: 69

Related Questions