Сегодня я покажу один простой, но довольно практичный шаблон-преобразователь, сочетающий в себе массовый проход по некоторому набору данных и последующую компоновку этих данных либо в единый конгломерат, либо в единственное отображение из элементарного типа.
Данный шаблон, носит в некоторых кругах название transducer (т.е. массированный преобразователь данных) и пришел он в современное программирование из очень интересного и мощного языка программирования Clojure, где используется для обработки очень больших массивов данных.
Шаблон выглядит следующим образом:
auto transduce(alias f, alias g, Range)(Range range) { import std.algorithm : map, reduce; return range .map!f .reduce!g; }
Что интересно, применять его достаточно просто: необходимо определить (или построить in situ, т.е. на месте) две функции и подать их в шаблон вместе с данными, требующими обработки.
Вот простой пример использования, хотя применение шаблона ограничено только вашей фантазией и синтаксисом шаблона:
import std.conv : to; import std.stdio; void main() { import std.algorithm; import std.range; auto arr = [1,2,3,4,5]; arr .transduce!(a => to!float(a), (a,b) => a + b) .writeln; auto f(T)(T x) { return to!string(x); } arr .transduce!("to!string(a)", (a,b) => a ~= b) .writeln; }
Насколько я знаю, это лишь один из вариантов transducer, один из многих, но возможное поле действий таких преобразований очень и очень велико, что вероятно, будет затронуто в одной из более масштабных статей блога или же в целой группе статей-рецептов…