かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Reactive Extensions入門 9「合成(MergeとZip)」

さて、これまでは、単一のIObservableを相手にしてきましたが、複数のIObservableを合成して使う方法を紹介したいと思います。

Merge

単純に2つのIObservableをくっつけます。

var s1 = new Subject<string>();
var s2 = new Subject<string>();

// s1とs2を1つのIObservableとしてみる
s1.Merge(s2).Subscribe(Console.WriteLine);

s1.OnNext("s1-1");
s2.OnNext("s2-1");

s1.OnNext("s1-2");
s1.OnNext("s1-3");
s2.OnNext("s2-2");

s1とs2をマージして、1つにしてるので、s1とs2のOnNextが呼ばれた順番でConsole.WriteLineまで値が流れていきます。
実行結果

s1-1
s2-1
s1-2
s1-3
s2-2

Zip

これは、2つのIObservableから上がってきた値を使って新しい値を作ります。2つのIObservableからの値が揃わない限り次へは進みません。

var s1 = new Subject<string>();
var s2 = new Subject<string>();

// s1とs2からあがってきた値を" : "で連結する
s1.Zip(s2, (a, b) => a + " : " + b).Subscribe(Console.WriteLine);

s1.OnNext("s1-1");
s2.OnNext("s2-1");

s1.OnNext("s1-2");
s1.OnNext("s1-3");
s2.OnNext("s2-2");

実行結果

s1-1 : s2-1
s1-2 : s2-2

s1から3回値を発行していますが、s2からは2回しか値が発行されていないため、Subscribeにいく通知は2つになります。