かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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つになります。