Nobollel開発者ブログ

Nobollelのエンジニアが、UnityやCocos2d-xの旬な情報・技術を紹介します。

【Reactive Extensions】 IObservableの合成と分岐入門その3

おはこんばんにちは、tsuchimotoです。

今回は前回に引き続き、UniRxを使ったIObservableの合成と分岐入門の3回目になります。

前回までのリンク

SelectManyメソッド

SelectManyメソッドについて説明します。

SelectManyメソッドはざっくり言うとSelctメソッドとMergeメソッドを組合わせたものになります。

説明する前に前回紹介したMergeメソッドを再掲します。

// 返されたIObservable<T>をすべてマージ
public static IObservable<T> Merge<T>(this IObservable<IObservable<T>> sources);

このMergeメソッドのシグネチャIObservable<T>を返すようなIObservableを引数にとりました。

SelectManyメソッドのシグネチャは以下になります。

public static IObservable<R> SelectMany<T, R>(
    this IObservable<T> source,
    Func<T,IObservable<R>> selector
);

最初の引数はIObservable、2番目の引数はIObservable<R>を返すようなデリゲートをとります。

どこか似ていませんか?

そう、最初の引数と2番目の引数を組合わせると、Mergeメソッドの引数の形になるのです。

まとめると、もともとのIObservableを別のIObservableに変換して合成しているので、以下のように

Select(IObservableを別のIObservableに変換)して、Merge (合成)しているのと同じことなのです。

SelectMany(i => Observable.Return(i))
↓
Select(i => Observable.Return(i)).Merge()

SelectManyメソッドの使用例を以下に示します。

var source = new Subject<string>();
source
    // IObservable<string>からIObservable<IObservable<string>>に変換して合成
    .SelectMany(i => Observable
        // 0,1,2と値を3つ発行
        .Interval(TimeSpan.FromMilliseconds(250)).Take(3)
        // 値を変換
        .Select(j => i + j))
    // 購読
    .Subscribe(
        i => Debug.Log("OnNext: " +  i),
        i => Debug.Log("OnCompleted"));

// 値の発行
source.OnNext("a");
source.OnNext("b");
source.OnNext("c");
source.OnNext("d");

実行結果は以下のようになります。実行結果もSelect/Mergeの結果と全く同じになります。

OnNext: a0
OnNext: b0
OnNext: c0
OnNext: d0
OnNext: a1
OnNext: b1
OnNext: c1
OnNext: d1
OnNext: a2
OnNext: b2
OnNext: c2
OnNext: d2

次回はZipメソッド、CombineLatestメソッドについて解説します。