【Reactive Extensions】 IObservableの合成と分岐入門その4
おはこんばんにちは、tsuchimotoです。
今回は前回の第3回に引き続き、UniRxを使ったIObservableの合成と分岐入門の4回目になります。
前回までのリンク
- IObservableの合成と分岐入門その1(Concat, StartWith)
- IObservableの合成と分岐入門その2(Merge)
- IObservableの合成と分岐入門その3(SelectMany)
Zipメソッド
Zipメソッドについて説明します。
Zipメソッドは2つの合成元のシーケンスから流れてきた値が2つ揃った時点で初めて、合成後のIObservableのシーケンスに値が流れます。
Zipメソッドのシグネチャは以下になります。
public static IObservable<R> Zip<T, U, R>( // 1つ目のシーケンス this IObservable<T> first, // 2つ目のシーケンス IObservable<U> second, // 合成後のシーケンス Func<T, U, R> resultSelector);
Zipメソッドの使用例を以下に示します。
1秒間隔で0, 1, 2の値を発行するIObservableのシーケンスと100, 101, 102の値を発行するIObservableのシーケンスをZipメソッドで合成しています。
// 1秒間隔で0,1,2と発行される Observable.Interval(TimeSpan.FromSeconds(1)).Take(3) // Zipでまとめる .Zip( // 100, 101と発行される Observable.Range(100, 2), // 流れてきた値を元に文字列化 (l, r) => string.Format("{0}:{1}", l, r)) // 購読 .Subscribe( s => Debug.Log("OnNext: {0}", s), () => Debug.Log("OnCompleted"));
実行結果を以下に示します。
2つの発行された値が1つのシーケンスになって流れてくることが確認できると思います。
ただしここで注意したいのは、1番目のシーケンスから発行された「3」が2番目のシーケンスと揃わないので後続に流れてきません。
OnNext: 0:100 OnNext: 1:101 OnCompleted
CombineLatestメソッド
CombineLatestメソッドについて説明します。
Zipメソッドが両方のIObservableのシーケンスから値が発行されるのを待つのに対してCombineLatestメソッドは、 どちらか一方から値が発行されると、もう一方の最後に発行した値があるか確認し、あればそれを使って後続に値を流します。
このメソッドのシグネチャを以下に示します。
public static IObservable<R> CombineLatest<F, S, R>( this IObservable<F> first, IObservable<S> second, Func<F, S, R> resultSelector);
このメソッドのコード例を下記に示します。
先ほどのZipメソッドのコードとほぼ同じでZipメソッドがCombineLatestメソッドになっただけです。
// 1秒間隔で0,1,2と発行される Observable.Interval(TimeSpan.FromSeconds(1)).Take(3) // CombineLatestでまとめる .CombineLatest( // 100, 101と発行される Observable.Range(100, 2), // 流れてきた値を元に文字列化 (l, r) => string.Format("{0}:{1}", l, r)) // 購読 .Subscribe( s => Debug.Log("OnNext: {0}", s), () => Debug.Log("OnCompleted"));
このコードの実行結果を以下に示します。 始めに「100」が発行された後に2はつ目のシーケンスが発行されないので、後続には流れてきません。 「101」発行後に「0」が発行されて初めて後続に流れてきます。
OnNext: 0:101 OnNext: 1:101 OnNext: 2:101 OnCompleted