読者です 読者をやめる 読者になる 読者になる

プログラミングで世界を変える

ゲームプログラミングと技術のこと

UniRxのZip, ZipLatest, CombineLatestの挙動の比較

Unity プログラミング UniRx

ZipLatestについての日本語の情報が見つからなかったので書きます。

2016年2月のコミットくらいで追加されていました。 github.com

ソースコード

using UnityEngine;
using UniRx;
using System.Linq;

public class ZipLatest_test : MonoBehaviour
{
    Subject<string> A = new Subject<string> ();
    Subject<string> B = new Subject<string> ();

    void Start ()
    {
        Observable.Zip (A, B)
          .Select (_ => _ [0] + ", " + _ [1])
          .Subscribe (_ => Debug.Log ("Zip: " + _));

        Observable.ZipLatest (A, B)
          .Select (_ => _ [0] + ", " + _ [1])
          .Subscribe (_ => Debug.Log ("ZipLatest: " + _));

        Observable.CombineLatest (A, B)
          .Select (_ => _ [0] + ", " + _ [1])
          .Subscribe (_ => Debug.Log ("CombineLatest: " + _));

        A.OnNext ("A0");
        A.OnNext ("A1");
        B.OnNext ("B2");
        A.OnNext ("A3");
        B.OnNext ("B4");
        B.OnNext ("B5");
    }
}

結果

Zip

Zip: A0, B2
Zip: A1, B4
Zip: A3, B5

それぞれのストリームに送られてきたメッセージを保持し、1つずつ揃ったタイミングで流れます。

ZipLatest

ZipLatest: A1, B2
ZipLatest: A3, B4

それぞれのストリームに送られてきた最新のメッセージを保持し、2つ揃ったタイミングで流れます。

CombineLatest

CombineLatest: A1, B2
CombineLatest: A3, B2
CombineLatest: A3, B4
CombineLatest: A3, B5

それぞれの最新のメッセージを保持し、いずれかのストリームにメッセージが流れてきたタイミングで流れます。

Zip, ZipLatestと違い、最新の値は一度流れても保持され続けます。

参考

qiita.com

時系列順の表

内部の実装まで見てないので、集合表現とかはイメージです。

時系列 t0 t1 t2 t3 t4 t5 t6
Aに流れるメッセージ A0 A1 - A3 - - -
Bに流れるメッセージ - - B2 - B4 B5 -
Zip - A (A0) (A0,A1) (A0,A1) (A1,A3) (A1,A3) (A3) ()
Zip - B () () (B2) () (B4) (B5) ()
Zipの出力 - - A0, B2 - A1, B4 A3, B5 -
ZipLatest - A (A0) (A1) (A1) (A3) (A3) () ()
ZipLatest - B - - (B2) () (B4) (B5) ()
ZipLatestの出力 - - A1, B2 - A3, B4 - -
CombineLatest - A (A0) (A1) (A1) (A3) (A3) (A3) (A3)
CombineLatest - B - - (B2) (B2) (B4) (B5) (B5)
CombineLatestの出力 - - A1, B2 A3, B2 A3, B4 A3, B5 -

それぞれのA,Bが揃ったタイミングで後続に流れるイメージです。

補足ですが、CombineLatestのt6に関しては、値は保持されていますがメッセージが流れてきていないため、発火していません。

追記(7/4)

以下の記事に送っていたZipLatestの追加の編集リクエストが通ったので、よければそちらも参考にしてみてください。

qiita.com