scan
Una acumulación progresiva y perezosa — como reduce, pero emite todos los valores intermedios en lugar de solo el último.
Lección
scan es reduce/fold con sus pasos
intermedios a la vista: en lugar de colapsar un iterable en un único valor
final, emite todas las acumulaciones parciales, incluido el propio
valor inicial como primer valor. Ese detalle —que el primer valor es el
valor inicial— importa: scan(f, 0, [1, 2, 3]) emite cuatro
valores
(0 y luego tres sumas parciales), no tres.
scan1 es la variante sin valor inicial, portada de la sobrecarga
scan(f, iterable) de FxTS (sin argumento de valor inicial). Usa el
primer elemento del iterable como acumulador inicial y lo emite de
inmediato, y luego sigue plegando el resto, reflejando la relación de
reduce con fold. Sobre un iterable vacío,
scan1 no tiene primer elemento con el que arrancar, así que no
emite nada en absoluto. Ten en cuenta que no hay método de cadena para
scan1 (solo scan está en
Fx/FxAsync): llámalo en forma data-first,
scan1(f, iterable).
Ambos son perezosos: no se ejecuta nada hasta que tiras de los valores. En
el lado asíncrono, scanAsync/scan1Async siguen
plegando paso a paso y en orden (cada paso necesita el resultado
anterior), así que
.concurrent(n) no paraleliza el pliegue en sí; lo que sí hace
es permitir que una etapa de descarga aguas arriba se ejecute con
concurrencia, siempre que la propia función acumuladora sea barata. Mira la
Demo 2.
Demo 1 · Fundamentos — scan y scan1
Demo 2 · Asíncrono, con concurrencia aguas arriba
El pliegue en sí sigue siendo secuencial, pero la descarga que lo alimenta no tiene por qué serlo:
Pruébalo tú
Ejercicio: usa scan para producir un total acumulado de
pasos, con 0 como valor inicial.
reduce/fold — colapsa a un único valor final ·
flat — aplana iterables anidados ·
peek — observa sin transformar ·
concurrent — evaluación paralela