Question

How to Get the Current Index in a for-each Loop in Kotlin

kotlinandroidfor-loop

Question

In Kotlin, how can you access the current index while looping through a collection with a for-each style loop?

For example, I want to do something on every second iteration:

for (value in collection) {
    if (iterationNo % 2 == 0) {
        // do something
    }
}

In Java, this is often done with a traditional indexed loop:

for (int i = 0; i < collection.length; i++) {
    // use i
}

What is the Kotlin way to get the equivalent of i while iterating through a collection?

Short Answer

By the end of this page, you will understand how to access an element's index while looping in Kotlin. You will learn the most common options—withIndex(), forEachIndexed(), and a classic indexed loop—and when each one is most useful.

Concept

In Kotlin, a basic for (value in collection) loop gives you direct access to each element, but not its position. This is intentional: a for-each loop focuses on values, not indexes.

When you need both the element and its position, Kotlin provides built-in tools instead of making you manage a counter manually.

The most common choices are:

  • withIndex() for for loops
  • forEachIndexed() for functional-style iteration
  • indices or a classic range-based loop when you specifically need index-based access

Why this matters:

  • Sometimes logic depends on position, such as every second item
  • You may need to format output differently for the first or last item
  • You may need both the index and value when processing lists

In Kotlin, the preferred approach is usually to choose the loop style that matches your intention:

  • Need just values? Use for (value in collection)
  • Need value and index? Use withIndex() or forEachIndexed()
  • Need direct indexed access? Use indices

This keeps your code readable and avoids unnecessary manual counters.

Mental Model

Think of a collection like a row of lockers.

  • A plain for (value in collection) loop lets you open each locker and look at what's inside.
  • An indexed loop also tells you the locker number.

If you only care about the contents, the locker number does not matter. If you want to do something with every second locker, or print Item 0, Item 1, and so on, then you need both:

  • the locker number = index
  • the contents = value

Kotlin's withIndex() and forEachIndexed() are just convenient ways of giving you both pieces of information together.

Take Quiz

Syntax and Examples

Using withIndex()

This is the most direct Kotlin-style solution for a for loop.

val collection = listOf("a", "b", "c", "d")

for ((index, value) in collection.withIndex()) {
    if (index % 2 == 0) {
        println("Index $index contains $value")
    }
}

What this does

  • withIndex() pairs each element with its index
  • (index, value) uses destructuring to extract both parts
  • index % 2 == 0 checks for even indexes

Output:

Index 0 contains a
Index 2 contains c

Using forEachIndexed()

val collection = listOf("a", "b", "c", "d")

collection.forEachIndexed { index, value ->
    if (index % 2 == 0) {
        println("Index $index contains $value")
    }
}

This is useful if you like lambda-based collection operations.

Using indices

val collection = listOf("a", "b", "c", "d")

for (i in collection.indices) {
    if (i % 2 == 0) {
        println("Index $i contains ${collection[i]}")
    }
}

This is closer to the Java style and is useful when you need direct indexed access.

Every second iteration

If by "every second iteration" you mean indexes 1, 3, 5, ..., use:

if (index % 2 == 1)

If you mean indexes 0, 2, 4, ..., use:

if (index % 2 == 0)

Step by Step Execution

Consider this example:

val collection = listOf("red", "blue", "green", "yellow")

for ((index, value) in collection.withIndex()) {
    if (index % 2 == 0) {
        println("$index -> $value")
    }
}

Step-by-step

  1. collection contains 4 items:

    • index 0 = red
    • index 1 = blue
    • index 2 = green
    • index 3 = yellow
  2. collection.withIndex() creates pairs like:

    • (0, red)
    • (1, blue)
    • (2, green)
    • (3, yellow)
  3. First loop iteration:

    • index = 0
    • value = red
    • 0 % 2 == 0 is true
    • prints 0 -> red
  4. Second loop iteration:

    • index = 1
    • value = blue
    • 1 % 2 == 0 is false
    • nothing prints
  5. Third loop iteration:

    • index = 2
    • value = green
    • 2 % 2 == 0 is true
    • prints 2 -> green
  6. Fourth loop iteration:

    • index = 3
    • value = yellow
    • 3 % 2 == 0 is false
    • nothing prints

Final output:

0 -> red
2 -> green

Real World Use Cases

Getting the index during iteration is common in real programs.

UI rendering

You might style alternating rows differently:

items.forEachIndexed { index, item ->
    val rowStyle = if (index % 2 == 0) "light" else "dark"
    println("Render $item with $rowStyle style")
}

Numbered lists

val tasks = listOf("Write code", "Test app", "Deploy")

for ((index, task) in tasks.withIndex()) {
    println("${index + 1}. $task")
}

Skipping or processing alternate items

val values = listOf(10, 20, 30, 40, 50)

for ((index, value) in values.withIndex()) {
    if (index % 2 == 1) {
        println("Process: $value")
    }
}

CSV or file parsing

You may want to treat the first line differently:

lines.forEachIndexed { index, line ->
    if (index == 0) {
        println("Header: $line")
    } else {
        println("Data row: $line")
    }
}
Take Quiz

Real Codebase Usage

In real Kotlin codebases, developers usually pick the iteration style based on intent.

Common patterns

1. Prefer value-only loops when index is unnecessary

for (user in users) {
    println(user.name)
}

This is simpler and more readable.

2. Use withIndex() when writing a normal for loop

for ((index, user) in users.withIndex()) {
    println("$index: ${user.name}")
}

This is common when you want a straightforward loop with index access.

3. Use forEachIndexed() in collection pipelines

users.forEachIndexed { index, user ->
    if (user.isActive) {
        println("Active user #$index: ${user.name}")
    }
}

4. Use guard conditions with index-based logic

users.forEachIndexed { index, user ->
    if (index == 0) return@forEachIndexed
    println(user.name)
}

This skips the first element.

5. Use indices when you must read or update by position

val numbers = mutableListOf(1, 2, 3)

for (i in numbers.indices) {
    numbers[i] = numbers[i] * 2
}

This is useful when modifying elements by index.

Practical guidance

  • Use withIndex() for readable indexed for loops
  • Use forEachIndexed() for lambda style
  • Use indices when index access itself is the main goal
  • Avoid manual counters unless truly necessary

Common Mistakes

1. Expecting for (value in collection) to provide an index

This loop only gives you the value.

for (value in collection) {
    // no index variable exists here
}

Fix

Use withIndex() or forEachIndexed().

for ((index, value) in collection.withIndex()) {
    println(index)
}

2. Writing an invalid modulo condition

Broken code:

if (iterationNo % 2) {
    // do something
}

In Kotlin, % returns a number, not a boolean.

Fix

Compare the result explicitly:

if (index % 2 == 0) {
    // even index
}

3. Confusing iteration number with index

Indexes usually start at 0.

  • index 0 = first item
  • index 1 = second item

If you want every second item in human terms, make sure you choose the right condition.

if (index % 2 == 1) {
    // second, fourth, sixth items
}

4. Using 0..collection.size

Broken code:

for (i in 0..collection.size) {
    println(collection[i])
}

This includes collection.size, which is out of bounds.

Fix

Use indices or until.

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

or

for (i in 0 until collection.size) {
    println(collection[i])
}

5. Manually tracking an index when Kotlin already provides one

Less idiomatic:

var i = 0
for (value in collection) {
    println("$i -> $value")
    i++
}

This works, but built-in options are usually clearer.

Better

for ((index, value) in collection.withIndex()) {
    println("$index -> $value")
}

Comparisons

ApproachBest whenExampleNotes
for (value in collection)You only need valuesfor (name in names)Simplest and most readable
for ((index, value) in collection.withIndex())You need both index and value in a normal loopfor ((i, v) in list.withIndex())Very idiomatic Kotlin
collection.forEachIndexed { index, value -> }You prefer lambda stylelist.forEachIndexed { i, v -> }Good for functional-style code
for (i in collection.indices)You need direct index accesscollection[i]Useful for updating elements
Manual counterRare cases where built-ins do not fitvar i = 0Usually less clean

withIndex() vs forEachIndexed()

FeaturewithIndex()forEachIndexed()
StyleTraditional for loopLambda/callback style
ReadabilityVery clear for loopsGood in chained collection code
Access to value and indexYesYes
Best for beginnersOften yesAlso good, but slightly more abstract

Kotlin vs Java style

Language styleExampleTypical use
Kotlin value loopfor (value in collection)Clean iteration over elements
Kotlin indexed loopfor ((i, value) in collection.withIndex())Element plus position
Java classic loopfor (int i = 0; i < arr.length; i++)Manual index control
Take Quiz

Cheat Sheet

Quick reference

Value only

for (value in collection) {
    println(value)
}

Index + value with withIndex()

for ((index, value) in collection.withIndex()) {
    println("$index -> $value")
}

Index + value with forEachIndexed()

collection.forEachIndexed { index, value ->
    println("$index -> $value")
}

Index only

for (i in collection.indices) {
    println(i)
}

Every second item

Even indexes:

if (index % 2 == 0)

Odd indexes:

if (index % 2 == 1)

Safe indexed range

for (i in 0 until collection.size) {
    println(collection[i])
}

Avoid

for (i in 0..collection.size) // out of bounds risk

Rule of thumb

  • Need only values: for (value in collection)
  • Need index and value: withIndex() or forEachIndexed()
  • Need direct mutation/access by position: indices

FAQ

How do I get the index in a Kotlin for-each loop?

Use withIndex() in a for loop or forEachIndexed() in a lambda-based loop.

What is the Kotlin equivalent of Java's for (int i = 0; i < length; i++)?

Usually for (i in collection.indices) or for ((i, value) in collection.withIndex()), depending on whether you need the value directly.

How do I process every second element in Kotlin?

Use the index and test it with modulo:

if (index % 2 == 1)

or

if (index % 2 == 0)

depending on whether you want odd or even positions.

Is withIndex() better than a manual counter?

Usually yes. It is clearer, less error-prone, and more idiomatic in Kotlin.

Can I modify a list while using withIndex()?

You can read values easily, but if you need to update by position, looping over indices is often more appropriate.

Why does if (index % 2) not work in Kotlin?

Because % returns a number, and Kotlin requires a boolean condition. You must compare the result, such as index % 2 == 0.

Does Kotlin indexing start at 0?

Yes. The first element is at index 0, the second at index 1, and so on.

Take Quiz

Mini Project

Description

Build a small Kotlin program that prints a numbered to-do list and highlights every second item. This helps you practice getting both the index and the value during iteration, which is a common task in real applications such as rendering UI lists, formatting reports, or processing rows of data.

Goal

Create a Kotlin program that loops through a list of tasks, prints each task with its number, and marks every second task differently.

Requirements

  • Create a list with at least five task names.
  • Loop through the list using a Kotlin approach that gives both index and value.
  • Print each task as a numbered item starting from 1.
  • Add a label like (even index) or (odd index) based on the position.
  • Only print a special message for every second item.
Take Quiz

Keep learning

Related questions

View more