過去記事インデックス
- Reactive Extensions再入門 その1
- Reactive Extensions再入門 その2「IObservableインターフェースとIObserverインターフェース」
- Reactive Extensions再入門 その3「IObservableのファクトリメソッド」
- Reactive Extensions再入門 その4「Timer系のファクトリメソッド」
- Reactive Extensions再入門 その5「HotとCold」
- Reactive Extensions再入門 その6「HotなIObservableを作成するファクトリ」
- Reactive Extensions再入門 その7「LINQスタイルの拡張メソッド」
- Reactive Extensions再入門 その8「SkipとTakeメソッド」
- Reactive Extensions再入門 その9「Skip + Take + Repeat = ドラッグ」
- Reactive Extensions再入門 その10「Doメソッド」
- Reactive Extensions再入門 その11「Catchメソッド」
- Reactive Extensions再入門 その12「Finallyメソッドとリソース解放」
- Reactive Extensions再入門 その13「最後の値を取得するLatestとMostRecentメソッド」
- Reactive Extensions再入門 その14「Nextメソッド」
- Reactive Extensions再入門 その15「To*****系メソッド」
- Reactive Extensions再入門 その16「最大、最少、平均を求めるメソッド」
- Reactive Extensions再入門 その17「集計するメソッド」
- Reactive Extensions再入門 その18「CountメソッドとLongCountメソッド」
はじめに
今回は、AnyメソッドとAllメソッドについて紹介します。どちらもIObservable
Anyメソッド
次にAnyメソッドについて説明します。Anyメソッドは、引数で渡したデリゲートがtrueを返す要素が1つでもあればtrueを後続に流します。IObservable
var s = new Subject<int>(); // どれかが0以下かチェック s.Any(i => i <= 0) // 購読 .Subscribe( i => Console.WriteLine("Any(i => i <= 0) OnNext({0})", i), () => Console.WriteLine("Any(i => i <= 0) OnCompleted()")); // どれかが偶数かチェック s.Any(i => i % 2 == 0) // 購読 .Subscribe( i => Console.WriteLine("Any(i => i % 2 == 0) OnNext({0})", i), () => Console.WriteLine("Any(i => i % 2 == 0) OnCompleted()")); // 値の発行〜完了通知 Console.WriteLine("OnNext(1)"); s.OnNext(1); Console.WriteLine("OnNext(10)"); s.OnNext(10); Console.WriteLine("OnNext(100)"); s.OnNext(100); Console.WriteLine("OnCompleted()"); s.OnCompleted();
IObservable
OnNext(1) OnNext(10) Any(i => i % 2 == 0) OnNext(True) Any(i => i % 2 == 0) OnCompleted() OnNext(100) OnCompleted() Any(i => i <= 0) OnNext(False) Any(i => i <= 0) OnCompleted()
注目すべき点は、偶数の値が流れてきた時点で、Trueが後続に流れている点です。OnNext(10)の後にすぐログが出ていることが確認できます。一方、0以下の値は1つもIObservable
Allメソッド
次は、Allメソッドについて説明します。AllメソッドはAnyメソッドと異なり引数で渡したデリゲートが全てTrueになるかどうかを確認します。コード例を下記に示します。
var s = new Subject<int>(); // 全てが偶数かどうかをチェック s.All(i => i % 2 == 0) // 購読 .Subscribe( i => Console.WriteLine("All(i => i % 2 == 0) OnNext({0})", i), () => Console.WriteLine("All(i => i % 2 == 0) OnCompleted()")); // 全てが1000以下かどうかをチェック s.All(i => i <= 1000) // 購読 .Subscribe( i => Console.WriteLine("All(i => i <= 1000) OnNext({0})", i), () => Console.WriteLine("All(i => i <= 1000) OnCompleted()")); // 値の発行〜完了通知 Console.WriteLine("OnNext(1)"); s.OnNext(1); Console.WriteLine("OnNext(10)"); s.OnNext(10); Console.WriteLine("OnNext(100)"); s.OnNext(100); Console.WriteLine("OnCompleted()"); s.OnCompleted();
IObservable
OnNext(1) All(i => i % 2 == 0) OnNext(False) All(i => i % 2 == 0) OnCompleted() OnNext(10) OnNext(100) OnCompleted() All(i => i <= 1000) OnNext(True) All(i => i <= 1000) OnCompleted()
偶数かどうかを判断するデリゲートを渡したAllメソッドは、OnNext(1)が呼び出された段階でFalseになることが確定するので後続にFalseを流しています。1000以下かどうかを判断するデリゲートを渡したAllメソッドは1, 10, 100の値では、どれもFalseにならないためOnCompleted()が呼び出された時点でTrueになることが確定して、後続にTrueを流しています。AnyメソッドもそうですがAllメソッドは、流れてきた値にたいしてリアルタイムに反応できる点がとてもReactive Extensionsらしい特徴のメソッドになっています。