Стандартные модули 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);