銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

.NET 10 Preview1で追加されたOrderedDictionaryのTryAddメソッドについて

先日のC# Tokyoの .NET 10 Preview1 イベントでも紹介した機能になります。動画の中でGitHubのサンプルコードを口頭で説明したのですが、それを実際のコードに起こしてみました。

www.youtube.com

OrderedDictionaryにTryAddとTryGetValueというメソッドが追加されました。

github.com

どのような使い方をするかというと、このGitHubにも書かれていますが以下のようなコードを想定していそうです。単語が文字列中に何回出現するかをカウントするのに、出現した単語をキーにして出現回数を値に確保しています。

public static void Execute()
{
    //指定された文字列が何回出現したかをカウントする
    var text = "apple banana apple cherry banana apple";
    var orderedDictionary = new OrderedDictionary<string, int>();
    foreach (var word in text.Split(' '))
    {
        IncrementValue(orderedDictionary, word);
    }
    foreach (var pair in orderedDictionary)
    {
        Console.WriteLine($"{pair.Key}: {pair.Value}");
    }
}

private static void IncrementValue(OrderedDictionary<string, int> orderedDictionary, string key)
{
    if (!orderedDictionary.TryAdd(key, 1, out int index))
    {
        int value = orderedDictionary.GetAt(index).Value;
        orderedDictionary.SetAt(index, value + 1);
    }
}

他の使い方としては、キーに関連する値を配列としてすべて確保するという使い方もできそうです。

private static void AddValue(OrderedDictionary<string, string[]> orderedDictionary, string key, string value)
{
    if (!orderedDictionary.TryAdd(key, [value], out int index))
    {
        var array = orderedDictionary.GetAt(index).Value;
        orderedDictionary.SetAt(index, [.. array.Prepend(value)]);
    }
}

TryGetValueメソッドの方は、最初の例に追加してカウントダウンする処理も追加したい場合に使えそうです。

private static void DecrementValue(OrderedDictionary<string, int> orderedDictionary, string key)
{
    if (orderedDictionary.TryGetValue(key, out int value, out int index))
    {
        //カウントが0になる場合は削除する
        if (value == 1)
        {
            orderedDictionary.RemoveAt(index);
        }
        else
        {
            orderedDictionary.SetAt(index, value - 1);
        }
    }//存在しない場合は何もしない
}

コードはこのリポジトリで公開しています。

github.com