ソート済みのDictionaryを作る

Dictionaryクラスが順序を保証しない実装であるのに対し、SortedDictionaryはキーの順序を管理できるディクショナリです

並び順が保障されているDictionaryクラスですね

基本のソート

サンプル

SortedDictionary<string, int> ranking = new SortedDictionary<string, int>()
{
    ["BBさん"] = 50,
    ["DDDDさん"] = 100,
    ["CCCさん"] = 70,
};

foreach (var rank in ranking)
{
    Console.WriteLine(rank.Key + " + " + rank);
}

Console.WriteLine();

ranking.Add("Aさん", 70);

foreach (var rank in ranking)
{
    Console.WriteLine(rank.Key + " + " + rank);
}

DictionaryクラスをSortedDictionaryクラスへ変更して使います
使い方はDictionaryと同じです

SortedDictionary<string, int> ranking = new SortedDictionary<string, int>()

次の構文は、冗長ですが学習目的です
rank.keyのkeyの部分が取り出せます。値を取り出したいときは、rank.valueとします
直接rankを代入すると、Console.WriteLineメソッドの方でキーと値のセットを表示してくれます

Console.WriteLine(rank.Key + " + " + rank);

結果

既定でキーとなる型の自然順序(文字列ならば辞書順、数値ならば大小順)に従って要素の並びを管理されます
例では、キーが文字列なのでABC順に並び替えられているのがわかります

BBさん + [BBさん, 50]
CCCさん + [CCCさん, 70]
DDDDさん + [DDDDさん, 100]

Aさん + [Aさん, 70]
BBさん + [BBさん, 50]
CCCさん + [CCCさん, 70]
DDDDさん + [DDDDさん, 100]

ソート順をカスタムしたい場合

サンプル

SortedDictionary<string, int> ranking = new SortedDictionary<string, int>(new StringLengthComparer())
{
    ["BBさん"] = 50,
    ["DDDDさん"] = 100,
    ["CCCさん"] = 70,
};

foreach (var rank in ranking)
{
    Console.WriteLine(rank.Key + " + " + rank);
}

Console.WriteLine();

ranking.Add("Aさん", 70);

foreach (var rank in ranking)
{
    Console.WriteLine(rank.Key + " + " + rank);
}

class StringLengthComparer : IComparer<string>
{
    public int Compare(string? x, string? y)
    {
        return y.Length - x.Length;
    }
}

引数にコンペア条件を追加しています
new演算子でインスタンスを作って追加します

new SortedDictionary<string, int>(new StringLengthComparer())

コンペア条件を設定するためのクラスです
IComparerインターフェースを実装するクラスを作成することで上記の引数に代入することができるようになります

Compareメソッドは、

  • x < yの時は、負数
  • x = yの時は、0
  • x < yの時は、正数

を返すようにします
今回の例だと、y.Length – x.Lengthなので、キーの長い順になりますね

class StringLengthComparer : IComparer<string>
{
    public int Compare(string? x, string? y)
    {
        return y.Length - x.Length;
    }
}

結果

コンペア(比較)の条件がLength(長さ)順と指定しているので、今度は名前の長さ順で要素の並びが管理されます

DDDDさん + [DDDDさん, 100]
CCCさん + [CCCさん, 70]
BBさん + [BBさん, 50]

DDDDさん + [DDDDさん, 100]
CCCさん + [CCCさん, 70]
BBさん + [BBさん, 50]
Aさん + [Aさん, 70]

C#

Posted by hidepon