Distinct
1. 概要
Distinct は、ソースシーケンス全体で重複する要素を排除し、一意の要素のみを通過させるフィルタリングオペレーターです。過去に出現したすべての要素を記憶し、既に出現した要素は破棄します。
2. シグネチャ
デフォルト比較による重複排除
csharp
public static Observable<T> Distinct<T>(
this Observable<T> source)デフォルトの等値比較(EqualityComparer<T>.Default)を使用して重複を判定します。
csharp
// 重複する整数を排除
source.Distinct();カスタム比較子による重複排除
csharp
public static Observable<T> Distinct<T>(
this Observable<T> source,
IEqualityComparer<T> comparer)指定した IEqualityComparer<T> を使用して重複を判定します。大文字小文字を無視した文字列比較などに便利です。
csharp
// 大文字小文字を無視して重複排除
source.Distinct(StringComparer.OrdinalIgnoreCase);overload の使い分け
| overload | 使う場面 |
|---|---|
| 引数なし | デフォルトの等値比較で十分な場合 |
IEqualityComparer<T> | カスタムの比較ロジックが必要な場合 |
3. マーブルダイアグラム
最初に出現した要素はそのまま通過し、以降同じ値が出現しても破棄されます。内部に HashSet を保持し、シーケンス全体で一意性を保証します。
4. サンプルコード
csharp
using R3;
// 基本的な重複排除
var values = new[] { 1, 2, 3, 2, 1, 4, 3, 5 };
values.ToObservable()
.Distinct()
.Subscribe(x => Console.WriteLine($"値: {x}"));
// 出力:
// 値: 1
// 値: 2
// 値: 3
// 値: 4
// 値: 5
// カスタム比較子を使った重複排除
var words = new[] { "Apple", "banana", "apple", "BANANA", "Cherry" };
words.ToObservable()
.Distinct(StringComparer.OrdinalIgnoreCase)
.Subscribe(w => Console.WriteLine($"単語: {w}"));
// 出力:
// 単語: Apple
// 単語: banana
// 単語: Cherry5. 補足
DistinctUntilChanged との違い
Distinct: シーケンス全体で重複を排除します。過去に出現したすべての値を記憶するため、メモリを消費します。無限シーケンスで多様な値が流れる場合はメモリリークに注意してください。- DistinctUntilChanged: 直前の要素とのみ比較し、連続する重複だけを排除します。メモリ消費は一定です。
多くのリアクティブなユースケース(UI 状態の変更通知など)では、連続する重複のみ排除すれば十分なため、DistinctUntilChanged のほうが適切です。
DistinctBy との違い
要素そのものではなく、特定のプロパティ(キー)に基づいて重複を判定したい場合は DistinctBy を使用してください。