6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

別ストリームの現在値を使いたい

Last updated at Posted at 2015-09-07

Rxで何でもかんでもIObservable<T>で書こうとすると
triggerストリームの発行タイミングで、sourceストリームの最終値を後続に流したい」
ということがよくある。
例えば「ファイルに保存ボタンクリック」イベントストリームの発行タイミングで、「ファイル名」ストリームの現在値を後続に流したい。など。

適当にlatestValueなるフィールドを用意して

source.Subscribe(x => latestValue = x);
trigger.Subscribe(_ => FooBar(latestValue));

こうしてやれば実現できるが、なるべくIObservableでやりたい気分のときどうするか。

Sample()

似たような動きをするのがSample()メソッドであるが、
こいつはsourceが値を発行しない間にtriggerを数発発行しても、最初の一発しかサンプリングしてくれない。

Sample()メソッド:
source   ---1-------2------3------4--
trigger  -------o----o-o--o----o-----
          source.Sample(trigger)
         -------1----2---------3-----

やりたい方:
source   ---1-------2------3------4--
trigger  -------o----o-o--o----o-----
                  ???
         -------1----2-2--2----3-----

CombineLatest()

triggerの分だけ発行してくれるが、sourceの変更でも発行してしまう。

source   ---1-------2--------3------4--
trigger  -------o-----o-o--o-----o-----
          source.CombineLatest(trigger,(s,t)=>s)
         -------1---2-2-2--2-3---3--4--

これではテキストボックスに文字打っただけで保存してしまう。

Sample().CombineLatest()

目的のストリームが得られる。

source   ---1-------2------3------4--
trigger  -------o----o-o--o----o-----
         source.Sample(trigger)
         -------1----2---------3-----
         .CombineLatest(trigger,(s,t)=>s)
         -------1----2-2--2----3-----

CombineLatest().DistictUntilChanged()

triggerをとにかく前回と違う値を流すストリームに変換して(例えばScan()でインクリメントさせる)
sourceとCombineLatest()して、trigger変換ストリームの値をキーにしてDistictUntilChanged()する。

source   ---1-------2--------3------4--------
trigger  -------o------o--o-----o------o-----
trigger' -------A------B--C-----D------E-----
         .CombineLatest(trigger,(s,t)=>new {src = s, trg = t})
         -------1A--2A-2B-2C-3C-3D--4D-4E----
         .DistictUntilChanged(x => x.trg)
         -------1A-----2B-2C----3D-----4E----
         .Select(x => x.src)
         -------1------2--2-----3------4-----

おわり

定番パターン集みたいなのが少ないので、いまいち自分がまわりくどいor不確実な実装をしているような気がしてならない。

6
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?