uniqStrict

Deduplica el iterable entero de inmediato y devuelve una List: la contraparte estricta de distinct.

List<A> uniqStrict<A>(Iterable<A> iterable) List<A> uniqByStrict<A, B>(B Function(A a) f, Iterable<A> iterable) Fx<T> Fx.uniqStrict() // chain Fx<T> Fx.uniqByStrict<B>(B Function(T a) f)

Lección

uniqStrict produce exactamente los mismos elementos, en el mismo orden, que distinct seguido de toList(). Lo que cambia es cuándo ocurre el trabajo y quién puede detenerlo. uniqByStrict hace el mismo trato para distinctBy: deduplicar por una clave calculada, de forma inmediata.

Una cadena perezosa vuelve a ejecutar su origen en cada recorrido. Recorre distinct(...) dos veces y la fuente se recorre dos veces. La forma estricta la recorre una sola vez, en la llamada, y te entrega una List: así, un resultado que vas a indexar, medir o recorrer más de una vez te cuesta una pasada en lugar de n. La Demo 2 cuenta las llamadas al callback para hacerlo evidente.

El precio es que nada aguas abajo puede interrumpir el trabajo. distinct(xs).take(3) deja de tirar de xs en cuanto han aparecido 3 valores distintos; uniqStrict(xs).take(3) deduplica todo xs primero y luego toma 3. Nunca pongas la forma estricta delante de un consumidor que corta pronto, y nunca la apuntes a un iterable infinito: no terminará.

Por defecto, perezoso. distinct(...).toList() ya ejecuta la deduplicación y la acumulación en una sola pasada, así que no estás pagando por la pereza. Recurre a uniqStrict solo cuando la List deduplicada sea en sí misma lo que quieres, o cuando se recorra más de una vez.

Demo 1 · Lo básico

Demo 2 · Cuándo compensa y qué cuesta

Pruébalo tú

Ejercicio: usa uniqByStrict para quedarte con la primera visita de cada visitante, como una List que puedas indexar sin volver a recorrerla.

Relacionados: distinct — el valor por defecto, perezoso · distinctBy — deduplicar por una clave calculada · uniqAdjacent — quitar solo duplicados adyacentes · toList — materializar cualquier cadena