Стандартные модули std.range и std.algorithm предоставляют множество великолепных функций, которые могут быть скомпонованы для выражения сложных операций, при этом оставаясь простыми для чтения. В основе этих функций лежат диапазоны.
Замечательная особенность таких алгоритмов в том, что вам лишь требуется определить собственный диапазон, и вы сможете использовать все возможности стандартной библиотеки.
filter - Используя лямбда-выражение, передаваемое как
параметр шаблона, генерирует новый диапазон,
фильтрующий элементы:
filter!"a > 20"(range);
filter!(a => a > 20)(range);
map - Генерирует новый диапазон, используя предикат,
передаваемый как параметр шаблона:
[1, 2, 3].map!(x => to!string(x));
each - foreach "для бедных" - функция, итерирующая
диапазон:
[1, 2, 3].each!(a => writeln(a));
take - Взять N элементов:
theBigBigRange.take(10);
zip - одновременно итерирует два диапазона,
возвращает tuple - пары элементов из обоих
диапазонов:
assert(zip([1,2], ["hello","world"]).front
== tuple(1, "hello"));
generate - создаёт диапазон, вызывая переданную
функцию в каждой итерации:
alias RandomRange = generate!(x => uniform(1, 1000));
cycle - возвращает диапазон, бесконечно повторяющий
переданный диапазон ввода:
auto c = cycle([1]);
// диапазон никогда не будет пуст!
assert(!c.empty);