Comment obtenir l'indice actuel dans forEach Kotlin : du débutant au pro
\n\nImaginez : vous codez en Kotlin, vous traitez une liste d'utilisateurs, et soudain vous réalisez que vous avez besoin non seulement de l'élément, mais aussi de sa position dans la collection. Vous tendez machinalement la main vers l'ancien for (i in 0 until list.size)… Stop ! Kotlin propose des méthodes plus élégantes et performantes. Dans cet article, nous allons voir comment obtenir l'indice actuel dans forEach Kotlin, comparer les performances des différentes approches et choisir la meilleure pour votre projet. Ce n'est pas une simple traduction de documentation — c'est le résultat de mesures réelles et de l'expérience de la communauté Stack Overflow.
Pourquoi forEach sans indice est un problème ?
\n\nLe standard list.forEach { item -> ... } est pratique, mais quand on a besoin de connaître la position de l'élément, beaucoup écrivent des béquilles :
var index = 0\nlist.forEach { item ->\n println("$index: $item")\n index++\n}\n\nCela fonctionne, mais c'est lourd et sujet aux erreurs (oubli de l'incrémentation ? bug assuré). De plus, une variable mutable en dehors de la boucle est une violation du style fonctionnel et un problème potentiel dans les scénarios multithreads. Voyons les bonnes solutions.
\n\nMéthode 1 : Utiliser withIndex() — simple et élégant
\n\nLa réponse la plus populaire sur Stack Overflow est la fonction withIndex(). Elle retourne une séquence de paires IndexedValue, où chaque élément a un champ index et value.
val list = listOf("Kotlin", "Java", "Python")\nlist.withIndex().forEach { (index, value) ->\n println("Élément #$index: $value")\n}\n\nQue se passe-t-il ici ? withIndex() crée une séquence paresseuse (lazy) qui enveloppe chaque élément dans un objet IndexedValue. La déstructuration (index, value) rend le code propre et lisible.
Avantages :
\n- \n
- Concision — une ligne au lieu de trois \n
- Paresse — ne crée pas de collections inutiles en mémoire \n
- Lisibilité — on voit immédiatement qu'on travaille avec un indice \n
Inconvénients :
\n- \n
- Léger surcoût dû à la création de l'enveloppe
IndexedValue(cependant, dans 99% des cas, c'est imperceptible) \n
Méthode 2 : forEachIndexed — une alternative intégrée
\n\nKotlin fournit une fonction prête à l'emploi forEachIndexed, qui prend une lambda avec deux paramètres : l'indice et la valeur.
list.forEachIndexed { index, value ->\n println("Position $index: $value")\n}\n\nC'est pratiquement la même chose que withIndex().forEach, mais sans appel supplémentaire. L'implémentation interne de forEachIndexed utilise-t-elle aussi IndexedValue ? Non, elle transmet l'indice directement, ce qui est légèrement plus rapide.
Avantages :
\n- \n
- Écriture la plus courte possible \n
- Pas de création d'objets intermédiaires \n
- Idiomatique pour Kotlin \n
Inconvénients :
\n- \n
- Moins flexible que
withIndex()— impossible de combiner avec d'autres opérateurs de chaîne (par exemple,filteravantforEach) \n
Méthode 3 : filterIndexed — quand il faut filtrer par indice
\n\nSi vous avez besoin non seulement d'obtenir l'indice, mais aussi de filtrer les éléments selon leur position, filterIndexed est votre choix.
val list = listOf("a", "b", "c", "d", "e")\nval evenIndexed = list.filterIndexed { index, _ -> index % 2 == 0 }\nprintln(evenIndexed) // [a, c, e]\n\nNotez : le deuxième paramètre est l'élément lui-même, mais nous l'ignorons en utilisant _. C'est une pratique courante en Kotlin pour les variables inutilisées.
Avantages :
\n- \n
- Flexibilité — possibilité de combiner filtrage et transformation \n
- Style fonctionnel pur \n
Inconv