Indices in forEach Kotlin: How Not to Lose Position and Speed Up Code

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

How to Get the Current Index in forEach Kotlin: From Beginner to Pro

\n\n

Imagine: you're writing in Kotlin, processing a list of users, and suddenly you realize you need not only the element but also its position in the collection. You instinctively reach for the old-fashioned for (i in 0 until list.size)… Stop! Kotlin has more elegant and performant ways. In this article, we'll break down how to get the current index in forEach Kotlin, compare the performance of different approaches, and choose the best one for your project. This is not just a translation of the documentation — it's the result of real-world benchmarks and community experience from Stack Overflow.

\n\n

Why is forEach Without an Index a Problem?

\n\n

The standard list.forEach { item -> ... } is convenient, but when you need to know the element's position, many people write workarounds:

\n\n
var index = 0\nlist.forEach { item ->\n    println("$index: $item")\n    index++\n}
\n\n

This works, but it looks cumbersome and is error-prone (forgot the increment? you get a bug). Moreover, a mutable variable outside the loop is a violation of functional style and a potential problem in multithreaded scenarios. Let's look at the correct solutions.

\n\n

Method 1: Using withIndex() — Simple and Elegant

\n\n

The most popular answer on Stack Overflow is the withIndex() function. It returns a sequence of IndexedValue pairs, where each element has an index and value field.

\n\n
val list = listOf("Kotlin", "Java", "Python")\nlist.withIndex().forEach { (index, value) ->\n    println("Element #$index: $value")\n}
\n\n

What's happening here? withIndex() creates a lazy sequence that wraps each element in an IndexedValue object. Destructuring (index, value) makes the code clean and readable.

\n\n

Pros:

\n
    \n
  • Conciseness — one line instead of three
  • \n
  • Laziness — doesn't create extra collections in memory
  • \n
  • Readability — it's immediately clear we're working with an index
  • \n
\n\n

Cons:

\n
    \n
  • Slight overhead from creating the IndexedValue wrapper (though in 99% of cases this is negligible)
  • \n
\n\n

Method 2: forEachIndexed — Built-in Alternative

\n\n

Kotlin provides a ready-made function forEachIndexed, which takes a lambda with two parameters: index and value.

\n\n
list.forEachIndexed { index, value ->\n    println("Position $index: $value")\n}
\n\n

This is practically the same as withIndex().forEach, but without an extra call. Does the internal implementation of forEachIndexed also use IndexedValue? No, it passes the index directly, which is slightly faster.

\n\n

Pros:

\n
    \n
  • Most concise notation
  • \n
  • No intermediate object creation
  • \n
  • Idiomatic for Kotlin
  • \n
\n\n

Cons:

\n
    \n
  • Less flexible than withIndex() — cannot be combined with other chaining operators (e.g., filter before forEach)
  • \n
\n\n

Method 3: filterIndexed — When You Need to Filter by Index

\n\n

If you need not just to get the index but also to filter elements by their position, filterIndexed is your choice.

\n\n
val list = listOf("a", "b", "c", "d", "e")\nval evenIndexed = list.filterIndexed { index, _ -> index % 2 == 0 }\nprintln(evenIndexed) // [a, c, e]
\n\n

Note: the second parameter is the element itself, but we ignore it using _. This is standard practice in Kotlin for unused variables.

\n\n

Pros:

\n
    \n
  • Flexibility — can combine filtering and transformation
  • \n
  • Clean functional style
  • \n
\n\n

Cons:

\n
    \n
  • Mi

Blogs

Book Recommendations