Where
1. 概要
Where は、ソースシーケンスの各要素に対して条件(predicate)を評価し、条件を満たす要素のみを通過させるフィルタリングオペレーターです。LINQ の Where と同様の動作で、リアクティブシーケンスにおける最も基本的なフィルタリング手段です。
2. シグネチャ
条件関数によるフィルタリング
csharp
public static Observable<T> Where<T>(
this Observable<T> source,
Func<T, Boolean> predicate)条件関数 predicate が true を返す要素のみを下流に流します。
csharp
// 偶数のみ通過させる
source.Where(x => x % 2 == 0);インデックス付き条件関数によるフィルタリング
csharp
public static Observable<T> Where<T>(
this Observable<T> source,
Func<T, int, Boolean> predicate)条件関数の第 2 引数に 0 始まりのインデックスが渡されます。要素の位置に基づくフィルタリングが可能です。
csharp
// 3 番目以降(index >= 2)かつ正の値のみ通過させる
source.Where((x, index) => index >= 2 && x > 0);overload の使い分け
| overload | 使う場面 |
|---|---|
Func<T, Boolean> | 要素の値だけで判定できる場合(一般的) |
Func<T, int, Boolean> | 要素の出現順序(インデックス)も判定に必要な場合 |
3. マーブルダイアグラム
ソースシーケンスの各要素に対して条件を評価し、条件を満たす要素(図中の色付き要素)のみが下流に流れます。条件を満たさない要素は破棄されます。
4. サンプルコード
csharp
using R3;
// 基本的なフィルタリング:偶数のみ取得
var source = Observable.Range(1, 10);
source
.Where(x => x % 2 == 0)
.Subscribe(x => Console.WriteLine($"偶数: {x}"));
// 出力:
// 偶数: 2
// 偶数: 4
// 偶数: 6
// 偶数: 8
// 偶数: 10
// インデックス付きフィルタリング:最初の 3 要素をスキップしつつ条件を適用
var values = new[] { 10, -5, 3, 7, -2, 8 };
values.ToObservable()
.Where((x, index) => index >= 3 && x > 0)
.Subscribe(x => Console.WriteLine($"値: {x}"));
// 出力:
// 値: 7
// 値: 85. 補足
WhereAwait との違い
条件判定に非同期処理(HTTP リクエストやデータベースクエリなど)が必要な場合は WhereAwait を使用してください。Where は同期的な条件関数のみをサポートします。
WhereSelect 最適化
R3 の内部実装では、Where の直後に Select をチェーンした場合、WhereSelect という最適化されたオペレーターに自動的に結合されます。これにより、2 つのオペレーターを個別に実行するよりもオーバーヘッドが削減されます。
csharp
// 内部的に WhereSelect に最適化される
source
.Where(x => x > 0)
.Select(x => x * 2);この最適化はユーザーが意識する必要はなく、自動的に適用されます。