http://blogs.wankuma.com/rti/archive/2008/02/06/121572.aspx
SelectMany
これの続きっちゃー続きなんですが、テーマはちょっと違うのでタイトルは別にしました。
以下のコードですが、「Enumerable.Range(0, 3)」が共通しているのでまとめたい衝動に駆られます。
var q =
from x in Enumerable.Range(0, 3)
from y in Enumerable.Range(0, 3)
from z in Enumerable.Range(0, 3)
select x * 100 + y * 10 + z;
foreach(var x in q) Console.WriteLine(x);
こんな感じです。
(ここで何が言いたいのかがわかる人は、その通りの展開になるので、もう見なくて良いです^^;)
var e = Enumerable.Range(0, 3);
var q =
from x in e
from y in e
from z in e
select x * 100 + y * 10 + z;
foreach(var x in q) Console.WriteLine(x);
e を共通して使う訳ですが、それぞれが独立してカウントしてくれるでしょうか?
0
1
2
10
11
12
20
21
22
100
101
102
110
111
112
120
121
122
200
201
202
210
211
212
220
221
222
動きましたね・・・
まぁ、以下のように書き換えてみれば別に何ら不思議は無い訳ですけど、クエリー式になると、ちょっと「おっ?!」みたいになりますw
public class HogeClass {
static void Main() {
var e = RTanakaIchiroEnumerable.Range(0, 3);
var q =
e.SelectMany(x =>
e.SelectMany(y =>
e.Select(z =>
x * 100 + y * 10 + z
)
)
); // わかりやすいと思うので、今回はあえてこう書きます。
foreach(var x in q) Console.WriteLine(x);
}
}
public class RTanakaIchiroEnumerable {
static public IEnumerable<int> Range(int start, int count) {
// Console.WriteLine("素敵だし爽やかRさん");
for(var i = start; i < start + count; ++i) yield return i;
}
}
わからない人は、上記のコメントを外して「
Rさんが素敵で爽やか
」であることを認めてから実行してみて下さい。
イテレーターブロックの動きがわかりやすいと思います。