Cómo obtener el índice actual en forEach Kotlin: de principiante a profesional
\n\nImagine: está escribiendo en Kotlin, procesando una lista de usuarios, y de repente se da cuenta de que necesita no solo el elemento, sino también su posición en la colección. Instintivamente, recurre al anticuado for (i in 0 until list.size)… ¡Alto! En Kotlin hay formas más elegantes y eficientes. En este artículo, analizaremos cómo obtener el índice actual en forEach Kotlin, compararemos el rendimiento de diferentes enfoques y elegiremos el mejor para su proyecto. Esto no es solo una traducción de la documentación, es el resultado de mediciones reales y la experiencia de la comunidad de Stack Overflow.
¿Por qué forEach sin índice es un problema?
\n\nEl estándar list.forEach { item -> ... } es conveniente, pero cuando necesita saber la posición del elemento, muchos escriben parches:
var index = 0\nlist.forEach { item ->\n println("$index: $item")\n index++\n}\n\nEsto funciona, pero se ve engorroso y es propenso a errores (¿olvidó el incremento? obtuvo un bug). Además, una variable mutable fuera del bucle es una violación del estilo funcional y un problema potencial en escenarios de subprocesos múltiples. Veamos las soluciones correctas.
\n\nMétodo 1: Usar withIndex() — simple y elegante
\n\nLa respuesta más popular en Stack Overflow es la función withIndex(). Devuelve una secuencia de pares IndexedValue, donde cada elemento tiene un campo index y value.
val list = listOf("Kotlin", "Java", "Python")\nlist.withIndex().forEach { (index, value) ->\n println("Elemento #$index: $value")\n}\n\n¿Qué sucede aquí? withIndex() crea una secuencia perezosa (lazy) que envuelve cada elemento en un objeto IndexedValue. La desestructuración (index, value) hace que el código sea limpio y legible.
Ventajas:
\n- \n
- Concisión — una línea en lugar de tres \n
- Perezosa — no crea colecciones adicionales en memoria \n
- Legibilidad — se ve de inmediato que estamos trabajando con un índice \n
Desventajas:
\n- \n
- Pequeña sobrecarga al crear el envoltorio
IndexedValue(aunque en el 99% de los casos es imperceptible) \n
Método 2: forEachIndexed — alternativa integrada
\n\nKotlin proporciona la función lista forEachIndexed, que acepta una lambda con dos parámetros: índice y valor.
list.forEachIndexed { index, value ->\n println("Posición $index: $value")\n}\n\nEsto es prácticamente lo mismo que withIndex().forEach, pero sin una llamada adicional. ¿La implementación interna de forEachIndexed también usa IndexedValue? No, pasa el índice directamente, lo que es un poco más rápido.
Ventajas:
\n- \n
- Escritura máxima corta \n
- Sin creación de objetos intermedios \n
- Idiomático para Kotlin \n
Desventajas:
\n- \n
- Menos flexible que
withIndex()— no se puede combinar con otros operadores de cadena (por ejemplo,filterantes deforEach) \n
Método 3: filterIndexed — cuando necesita filtrar por índice
\n\nSi no solo necesita obtener el índice, sino también filtrar elementos por su posición, filterIndexed es su elección.
val list = listOf("a", "b", "c", "d", "e")\nval evenIndexed = list.filterIndexed { index, _ -> index % 2 == 0 }\nprintln(evenIndexed) // [a, c, e]\n\nTenga en cuenta: el segundo parámetro es el elemento en sí, pero lo ignoramos usando _. Esta es una práctica estándar en Kotlin para variables no utilizadas.
Ventajas:
\n- \n
- Flexibilidad — se puede combinar filtrado y transformación \n
- Estilo funcional puro \n
Des