mapWithIndex & friends
Los cuatro operadores que conocen el índice: map, filter, flatMap y fold con la posición del elemento como segundo argumento.
Lección
zipWithIndex ya te da la
posición: empareja cada elemento con su índice y luego lees el par. Eso
funciona, y es la herramienta correcta cuando el par es lo que quieres.
Cuando no lo es, pagas un record por elemento y un cuerpo de callback
escrito con p.$1 / p.$2 en vez de con nombres.
Estos cuatro reciben el índice directamente. No hay nada que reservar ni nada que desempaquetar, y la cadena dice lo que hace.
El índice cuenta la entrada de esa etapa. No es la
posición del elemento en la fuente original: un
filter por encima de
mapWithIndex renumera lo que lo atraviesa, empezando otra vez
en 0. El que hay que leer dos veces es filterWithIndex: su
cuenta avanza también con los elementos que descarta, porque
siguen siendo entrada. flatMapWithIndex cuenta elementos de
la fuente, no emitidos, así que un iterable interno de cinco valores
avanza el índice en uno.
Todos tienen su forma …Async, y la numeración sobrevive a
concurrent: solapa los tirones
aguas arriba pero los resuelve igualmente en orden, así que el elemento
n recibe el índice n fueran cuales fueran las latencias.
El contador vive además por iteración, así que volver a recorrer
una cadena empieza otra vez en 0.
Una arruga de Dart en foldWithIndex: si el lambda del
acumulador no lleva tipos, Acc se infiere como
Object? y la aritmética deja de compilar. No es nada nuevo de
aquí — el propio Iterable.fold de Dart se comporta igual — y
la solución es la misma: escribe
foldWithIndex<int>(…).
Demo 1 · mapWithIndex, y a qué sustituye
Demo 2 · filter, flatMap, fold — y asíncrono
Pruébalo tú
Ejercicio: numera a los que llegan a meta como 1st, 2nd, 3rd usando el índice.