...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

std.algorithm - map, reduce

dmd 2.011になって,string mixinが標準ライブラリに取り込まれ始めた.

import std.algorithm, std.stdio;
alias writefln p;//面倒なのでよく使う(^^;
void main(){
  int[] arr = [1,2,3,4,5,6,7,8,9];
  p( map!("a*a")(arr) );

  int sum = reduce!("a+b")(0, arr);
  p( sum );
}

output:

[1 4 9 16 25 36 49 64 81]
45

map

まず,mapは配列の各要素に対して何らかの処理を実行してarrを書き換える.
テンプレート引数としてmixin用の文字列"a*a"を渡すと,下のようなデリゲートを渡したかのように振る舞う.

p( map!((int a){return a*a;})(arr) );

もちろん名前が付いた関数も与えることができる.

int sqr(int a){return a*a;}

p( map!(sqr)(arr) );

reduce

一方,reduceはもっと面白い.
まず,文字列"a+b"は,"a"が配列の最初の要素(int),"b"が配列の最初以外の要素すべて(int[])と見なされ,reduceは下のreduce_のような関数が暗黙裏に作成されたかのように振る舞う.

int reduce_(int a, int[] b){
    if (b.length > 1)
        return func(a, reduce_(b[0], b[1..$]));
    else
        return func(a, b[0]);
}
p( reduce_(0, arr) );

上のfuncが行う処理は,"a+b"の"+"によって決まり,この場合のfuncはこうだ.

int func(int a, int b) { return a + b; }