reduce
Colapsa un pipeline en un único valor, usando su primer elemento como valor inicial.
Lección
reduce es un operador terminal: a diferencia
de map o filter, llamarlo tira de inmediato de
todos los valores a través de todo el pipeline perezoso que tiene detrás y
produce un resultado concreto. Nada de lo que hay aguas arriba se ejecuta
hasta que llamas a un terminal como este.
Esta es la forma sin valor inicial: toma el primer elemento del
iterable como acumulador de partida y va combinando el resto sobre él. Por
eso mismo, llamarlo sobre un iterable vacío no tiene sentido —no hay primer
elemento del que partir— y por tanto lanza un StateError.
FxTS sobrecarga reduce para los casos con y sin valor inicial
según el número de argumentos: reduce(f, iterable) frente a
reduce(f, seed, iterable). Dart no tiene sobrecarga por
aridad, así que FxDart reserva reduce para la forma sin valor
inicial y renombra la otra como fold,
siguiendo la nomenclatura del propio Iterable.fold de Dart. Si
tienes un valor inicial, usa fold.
En la cadena síncrona, Fx extiende Iterable, así
que .reduce(f) es simplemente el método integrado de Dart:
mismo contrato, mismo StateError cuando está vacío. En la
cadena asíncrona, FxAsync.reduce está escrito de forma
explícita y espera cada paso de combinación.
Demo 1 · Fundamentos & el error con entrada vacía
Demo 2 · Asíncrono, con concurrencia
reduce sigue tirando de todo el pipeline que tiene detrás,
incluida una etapa .concurrent(n), que evalúa n
valores aguas arriba a la vez mientras reduce los combina
conforme van llegando en orden:
Pruébalo tú
Ejercicio: usa reduce para encontrar la palabra más larga de la lista.
fold — la contraparte con valor inicial ·
reduceLazy — un reductor currificado y reutilizable ·
sum — reduce especializado para números ·
concurrent — evaluación paralela aguas arriba