DistinctBy
1. 概要
DistinctBy は、指定したキーセレクターに基づいてソースシーケンス全体で重複を排除するフィルタリングオペレーターです。要素そのものではなく、要素から抽出したキーの一意性に基づいてフィルタリングを行います。同じキーを持つ要素のうち、最初に出現したもののみを通過させます。
2. シグネチャ
キーセレクターによる重複排除
csharp
public static Observable<TSource> DistinctBy<TSource, TKey>(
this Observable<TSource> source,
Func<TSource, TKey> keySelector)keySelector で抽出したキーが初めて出現する要素のみを通過させます。キーの比較にはデフォルトの等値比較を使用します。
csharp
// 同じ部署の最初のメンバーのみ取得
employees.DistinctBy(e => e.Department);キーセレクター+カスタム比較子による重複排除
csharp
public static Observable<TSource> DistinctBy<TSource, TKey>(
this Observable<TSource> source,
Func<TSource, TKey> keySelector,
IEqualityComparer<TKey> comparer)キーの比較に指定した IEqualityComparer<TKey> を使用します。
csharp
// カテゴリ名を大文字小文字無視で比較して重複排除
products.DistinctBy(p => p.Category, StringComparer.OrdinalIgnoreCase);overload の使い分け
| overload | 使う場面 |
|---|---|
keySelector のみ | デフォルトの等値比較で十分な場合 |
keySelector + comparer | キーの比較ロジックをカスタマイズしたい場合 |
3. マーブルダイアグラム
各要素からキーを抽出し、そのキーが初めて出現する場合のみ要素を下流に流します。同じキーを持つ 2 番目以降の要素は破棄されます。
4. サンプルコード
csharp
using R3;
// ユーザーのカテゴリごとに最初の 1 件だけ取得
var users = new[]
{
new { Name = "Alice", Role = "Admin" },
new { Name = "Bob", Role = "User" },
new { Name = "Charlie", Role = "Admin" },
new { Name = "Dave", Role = "User" },
new { Name = "Eve", Role = "Manager" }
};
users.ToObservable()
.DistinctBy(u => u.Role)
.Subscribe(u => Console.WriteLine($"{u.Role}: {u.Name}"));
// 出力:
// Admin: Alice
// User: Bob
// Manager: Eve
// カスタム比較子を使用した例
var items = new[] { "Apple", "apricot", "Banana", "avocado", "blueberry" };
items.ToObservable()
.DistinctBy(
s => s.Substring(0, 1), // 頭文字をキーとする
StringComparer.OrdinalIgnoreCase)
.Subscribe(s => Console.WriteLine($"フルーツ: {s}"));
// 出力:
// フルーツ: Apple
// フルーツ: Banana