1. Overview

Arrays serve as fundamental data structures for storing and manipulating collections of elements. Traversing an array in its natural order is a common task. However, there are scenarios where the need arises to iterate through it in reverse order.

In this tutorial, we’ll explore various methods to iterate through an array in the reverse order in Kotlin.

2. Introduction to the Problem

Kotlin simplifies array operations by providing concise syntax and built-in functions. Arrays can be easily initialized, manipulated, and, of course, traversed. For example, we can write a for loop to iterate over its elements or use the forEach{ … } function to traverse an array in its natural order.

However, when it comes to iterating through an array in reverse order, we may wonder if there’s a dedicated function or if a workaround is required.

In this tutorial, we’ll see different ways to solve this problem.

For example, let’s say we have an array of strings with six elements:

val array = arrayOf("a", "b", "c", "d", "e", "f")

If we reversely iterate this array, the expected order of accessing elements is “f” -> “e” -> “d” -> … -> “a”.

So, let’s store the elements in the expected order in a list so that we can verify whether our solutions of reverse iterations work as expected:

val reversedList = listOf("f", "e", "d", "c", "b", "a")

Next, let’s see how to iterate through array in reverse.

3. Calling the reversed() Function on the Array

Kotlin provides the Array.reversed() extension function. This function returns a new array with the elements in reverse order:

public fun <T> Array<out T>.reversed(): List<T> { ... }

For example, we can use a for loop to iterate through the result of array.reversed():

val resultList = mutableListOf<String>()
for (element in array.reversed()) {
    resultList += element
}
assertEquals(reversedList, resultList)

As the test shows, we first created an empty Mutablelist. While we iterated through the reversed array, we added each element to the mutable list.

Then, it turned out resultList is equal to the expected reversedList. So, we traversed the original array in reverse order.

4. Applying reversed() on the Array’s Index Range

The reversed() function is a straightforward solution. However, there are cases where direct indexing is preferred.

Kotlin’s array provides the indices property, holding the array’s indices in the natural order as an IntRange. Further, IntRange has the reversed() extension function as well.

Therefore, we can iterate through array.indices.reversed(), which provides a reversed range of valid indices, and then access array elements using the index:

val resultList = mutableListOf<String>()

for (i in array.indices.reversed()) {
    resultList += array[i]
}

assertEquals(reversedList, resultList)

5. Using the downTo() Function

In Kotlin, we can create a “reversed range” using the downTo() function. Technically speaking, Int.downTo()* returns an IntProgression instead of an *IntRange. 

IntProgession is the supertype of IntRange. The difference between IntRange and IntProgression is that IntRange* has the fixed step *1:

public class IntRange(start: Int, endInclusive: Int) : IntProgression(start, endInclusive, 1), ...{
    override val start: Int get() = first
    override val endInclusive: Int get() = last
    // ...
}

On the other hand, IntProgression allows us to specify the step value. For example, the downTo() function sets step = -1 automatically, so the integers are in the reverse order:

public infix fun Int.downTo(to: Int): IntProgression {
    return IntProgression.fromClosedRange(this, to, -1)
}

Thus, using array.lastIndex in conjunction with downTo() is another effective way to iterate through an array in reversed order in Kotlin. This approach directly manipulates the indices to achieve the desired result:

val resultList = mutableListOf<String>()
for (i in (array.lastIndex downTo 0)) {
    resultList += array[i]
}
assertEquals(reversedList, resultList)

It’s worth noting that “array.lastIndex downTo 0” in the above code is actually the function call “array.lastIndex.downTo(0)”. Since Int.downTo() is an infix extension function, we can write the function call in a more readable form.

6. Conclusion

In this article, we’ve explored different approaches to iterating an array in the reverse order in Kotlin.

If we don’t care about the array’s indices, array.reversed() is the most straightforward solution. Otherwise, two approaches can be chosen to directly index elements in reverse order: array.indices.reversed() and array.lastIndex downTo 0.

As always, the complete source code for the examples is available over on GitHub.