How to Get the Current Index in forEach Kotlin: From Beginner to Pro
\n\nImagine: 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.
Why is forEach Without an Index a Problem?
\n\nThe standard list.forEach { item -> ... } is convenient, but when you need to know the element's position, many people write workarounds:
var index = 0\nlist.forEach { item ->\n println("$index: $item")\n index++\n}\n\nThis 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\nMethod 1: Using withIndex() — Simple and Elegant
\n\nThe 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.
val list = listOf("Kotlin", "Java", "Python")\nlist.withIndex().forEach { (index, value) ->\n println("Element #$index: $value")\n}\n\nWhat'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.
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
Cons:
\n- \n
- Slight overhead from creating the
IndexedValuewrapper (though in 99% of cases this is negligible) \n
Method 2: forEachIndexed — Built-in Alternative
\n\nKotlin provides a ready-made function forEachIndexed, which takes a lambda with two parameters: index and value.
list.forEachIndexed { index, value ->\n println("Position $index: $value")\n}\n\nThis 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.
Pros:
\n- \n
- Most concise notation \n
- No intermediate object creation \n
- Idiomatic for Kotlin \n
Cons:
\n- \n
- Less flexible than
withIndex()— cannot be combined with other chaining operators (e.g.,filterbeforeforEach) \n
Method 3: filterIndexed — When You Need to Filter by Index
\n\nIf you need not just to get the index but also to filter elements by their position, filterIndexed is your choice.
val list = listOf("a", "b", "c", "d", "e")\nval evenIndexed = list.filterIndexed { index, _ -> index % 2 == 0 }\nprintln(evenIndexed) // [a, c, e]\n\nNote: the second parameter is the element itself, but we ignore it using _. This is standard practice in Kotlin for unused variables.
Pros:
\n- \n
- Flexibility — can combine filtering and transformation \n
- Clean functional style \n
Cons:
\n- \n
- Mi