Skip to content

ToDictionaryAsync

1. 概要

ToDictionaryAsync は、Observable シーケンスのすべての要素を収集し、Dictionary<TKey, T> または Dictionary<TKey, TElement>Task として返すオペレーターです。各要素からキーを抽出し、キーと値のペアとしてディクショナリに格納します。重複するキーが存在する場合は ArgumentException をスローします。

2. シグネチャ

キーセレクターのみ

csharp
public static Task<Dictionary<TKey, T>> ToDictionaryAsync<T, TKey>(
    this Observable<T> source,
    Func<T, TKey> keySelector,
    CancellationToken cancellationToken = default)
    where TKey : notnull

各要素からキーを抽出し、要素自体を値としてディクショナリに格納します。

キーセレクターと要素セレクター

csharp
public static Task<Dictionary<TKey, TElement>> ToDictionaryAsync<T, TKey, TElement>(
    this Observable<T> source,
    Func<T, TKey> keySelector,
    Func<T, TElement> elementSelector,
    CancellationToken cancellationToken = default)
    where TKey : notnull

各要素からキーと値の両方を変換してディクショナリに格納します。

キーセレクターとカスタム等値比較子

csharp
public static Task<Dictionary<TKey, T>> ToDictionaryAsync<T, TKey>(
    this Observable<T> source,
    Func<T, TKey> keySelector,
    IEqualityComparer<TKey> comparer,
    CancellationToken cancellationToken = default)
    where TKey : notnull

キーの比較にカスタムの IEqualityComparer<TKey> を使用します。

キーセレクター、要素セレクター、カスタム等値比較子

csharp
public static Task<Dictionary<TKey, TElement>> ToDictionaryAsync<T, TKey, TElement>(
    this Observable<T> source,
    Func<T, TKey> keySelector,
    Func<T, TElement> elementSelector,
    IEqualityComparer<TKey> comparer,
    CancellationToken cancellationToken = default)
    where TKey : notnull

キーと値の変換、およびカスタムのキー比較ロジックをすべて指定します。

オーバーロードの使い分け

オーバーロード用途
ToDictionaryAsync(source, keySelector)要素自体を値として格納する場合
ToDictionaryAsync(source, keySelector, elementSelector)値も変換したい場合
ToDictionaryAsync(source, keySelector, comparer)カスタムキー比較が必要な場合
ToDictionaryAsync(source, keySelector, elementSelector, comparer)値の変換とカスタムキー比較の両方が必要な場合

3. マーブルダイアグラム

ToDictionaryAsync のマーブルダイアグラム

シーケンスのすべての要素を収集し、完了時にキーと値のペアからなるディクショナリを単一の結果として出力します。

4. サンプルコード

csharp
// 基本的な使い方:キーセレクターのみ
var users = new[]
{
    new { Id = 1, Name = "田中" },
    new { Id = 2, Name = "鈴木" },
    new { Id = 3, Name = "佐藤" },
};

var dict = await users.ToObservable()
    .ToDictionaryAsync(u => u.Id);

Console.WriteLine(dict[2].Name); // 鈴木
csharp
// キーセレクターと要素セレクターを使用
var users = new[]
{
    new { Id = 1, Name = "田中" },
    new { Id = 2, Name = "鈴木" },
    new { Id = 3, Name = "佐藤" },
};

Dictionary<int, string> nameById = await users.ToObservable()
    .ToDictionaryAsync(u => u.Id, u => u.Name);

Console.WriteLine(nameById[1]); // 田中
csharp
// 重複キーがある場合は例外が発生
var items = new[] { "apple", "banana", "apricot" };

try
{
    var dict = await items.ToObservable()
        .ToDictionaryAsync(s => s[0]); // 先頭文字をキーに
}
catch (ArgumentException ex)
{
    Console.WriteLine("重複キーが検出されました");
    // 'a' が apple と apricot で重複
}