内包表記的な何か
早速作ってみました。
template comp(alias var){ U[] comp(T, U)(T ary, lazy U dg){ U[] ret; foreach (val; ary){ var = val; ret ~= dg; } return ret; } } void main(){ int x; int[] ary = [1, 2, 3, 4, 5]; foreach(v; comp!(x)(ary, x*x)){ writefln(v); } }
実行結果。
1 4 9 16 25
本当は、「ary.comp!(x)(x*x)」と書きたい…けど書けない。comp はテンプレートなので当然です。
「alias comp!(x) comp_」とかしておけば「ary.comp_(x*x)」と書けるんですが…わざわざ alias するのもダサい。
そして何よりの不満は、xを定義しないといけないこと…これはどうやら回避不可能のようです。悲しい。
追記:
関係無いテンプレートが入ってたので消しました…消した物は後で紹介するとして、最近こういうミス多いですね!それは兎も角。
http://d.hatena.ne.jp/nazodane/20061211/1165850649
今回は、Dでも簡単に元の配列の各要素を操作した配列を作れるといいな、と言うただそれだけの話でした。
つまるところRubyのmapみたいな物が欲しかったわけです。ただmap相当の物を作ろうとすると delegate を使う必要があって、そうなると。
map!(x)(ary, { return x*x; });
とかになるわけですが、これは面倒臭いので、諦めてlazy使ってます。
あくまでPythonのリスト内包表記の記法を真似するなら…
for__!(T) for_(T)(out T t){ return new for__!(T)(&t); } class for__(T){ T* ptr_; this(T* ptr){ ptr_ = ptr; } for___!(T) opIn(T[] ary){ return new for___!(T)(ptr_, ary); } } class for___(T){ T* ptr_; T[] ary_; this(T* ptr, T[] ary){ ptr_ = ptr; ary_ = ary; } U[] opShl_r(U)(lazy U dg){ U[] ret; foreach (val; ary_){ *ptr_ = val; ret ~= dg; } return ret; } } void main(){ int x; writefln(x*x << (for_(x) in [1, 2, 3, 4, 5])); // [1,4,9,16,25] int y; writefln(x*y << (for_(x) in [1, 2, 3]) << (for_(y) in [1, 2, 3])); // Pythonなら [1,2,3,2,4,6,3,6,9] だけど残念ながら [[1,2,3],[2,4,6],[3,6,9]] }
こんな感じでしょうか。
本当は「for_(x) in ary」の括弧を外したいんですが、演算子の適用順的に無理そうです。まあ式部分には必要ないみたいなのが救いです。