Los módulos std.range y std.algorithm de la librería estándar proporcionan una multitud de grandes funciones que permiten ser encadenadas para expresar operaciones complejas de forma legible, basándose en rangos como bloques de construcción.
Lo que hace grandes a estos algoritmos es que se pueden definir rangos propios y aprovecharse directamente de lo que ya está en la librería estándar.
std.algorithm
filter
: dada una función lambda como parámetro de plantilla, genera un nuevo
rango que filtra los elementos del rango pasado como argumento:
filter!"a > 20"(range);
filter!(a => a > 20)(range);
map
: genera un nuevo rango usando un predicado definido como parámetro de
plantilla:
[1, 2, 3].map!(x => to!string(x));
each
: el foreach
de los pobres cuya función pasada como parámetro se
aplica a cada elemento del rango:
[1, 2, 3].each!(a => writeln(a));
std.range
take
: limita el rango a N
elementos:
theBigBigRange.take(10);
zip
: itera sobre dos rangos en paralelo devolviendo un rango de tuplas
con cada pareja de elementos:
assert(zip([1,2], ["hello","world"]).front
== tuple(1, "hello"));
generate
: dada una función crea un rango que, en cada iteración, llama a
dicha función:
alias RandomRange = generate!(() => uniform(1, 1000));
cycle
: devuelve un rango que repite el rango de entrada de forma infinita:
auto c = cycle([1]);
// El rango nunca estará vacío.
assert(!c.empty);