web-dev-qa-db-ja.com

キーに関してディクショナリを所定の場所に並べ替える

私はC#のような辞書を持っています

Dictionary<Person, int>

そして、その辞書をソートしたいin placeキー(クラスPersonのフィールド)に関して。どうすればいいですか?インターネット上で利用可能なすべてのヘルプは、辞書のインプレースソートの特定の例のないリストのヘルプです。どんな助けも大歓迎です!

67
SoulReaver

Dictionary<TKey, TValue>を並べ替えることはできません-本質的に順序付けられていません。 (または、エントリが取得される順序は実装固有です。順序は設計された機能の一部ではないため、バージョン間で同じように動作することに依存しないでください。)

あなたはcanSortedList<TKey, TValue> または SortedDictionary<TKey, TValue> を使用できます。キーでソートする(構成可能な方法で、IEqualityComparer<T>をコンストラクターに渡す場合)-それらはあなたに役立つでしょうか?

SortedListという名前のWordの「リスト」にはほとんど注意を払わないでください-キーを値にマップするという点では、依然として辞書です。内部的にリストを使用してimplementedであるため、ハッシュコードで検索する代わりにバイナリ検索を実行します。 SortedDictionaryも同様にバイナリ検索に基づいていますが、リストではなくツリーを使用します。

141
Jon Skeet

SortedDictionary を使用してみてください

24
Chris O

正しい答えはすでに述べられています(SortedDictionaryを使用してください)。

ただし、コレクションを辞書として保持する必要がある場合は、リスト内のキーを並べ替えてから、このリストを使用して辞書にアクセスするなど、辞書キーに順番にアクセスすることができます。例...

Dictionary<string, int> dupcheck = new Dictionary<string, int>();

...「dupcheck」を埋めるコード、そして...

if (dupcheck.Count > 0) {
  Console.WriteLine("\ndupcheck (count: {0})\n----", dupcheck.Count);
  var keys_sorted = dupcheck.Keys.ToList();
    keys_sorted.Sort();
  foreach (var k in keys_sorted) {
    Console.WriteLine("{0} = {1}", k, dupcheck[k]);
  }
}

using System.Linq; このため。

10
Steve Greene

設計上、辞書はソートできません。辞書でこの機能が必要な場合は、代わりにSortedDictionaryをご覧ください。

7
Scott Dorman

SortedDictionaryを見てください。比較のために独自のIComparableを渡すことができるコンストラクターオーバーロードもあります。

4
Dave Downs

辞書はハッシュテーブルとして実装されますが、SortedDictionaryは赤黒ツリーとして実装されます。

アルゴリズムの順序を利用せず、出力前にデータを並べ替えるだけでよい場合、SortedDictionaryを使用するとパフォーマンスに悪影響があります

次のように辞書を「ソート」できます。

Dictionary<string, int> dictionary = new Dictionary<string, int>();
// algorithm
return new SortedDictionary<string, int>(dictionary);
3
Draex_

これは高い検索配置に答えるため、LINQ OrderByソリューションは示す価値があると思いました:

class Person
{
    public Person(string firstname, string lastname)
    {
        FirstName = firstname;
        LastName = lastname;
    }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

static void Main(string[] args)
{
    Dictionary<Person, int> People = new Dictionary<Person, int>();

    People.Add(new Person("John", "Doe"), 1);
    People.Add(new Person("Mary", "Poe"), 2);
    People.Add(new Person("Richard", "Roe"), 3);
    People.Add(new Person("Anne", "Roe"), 4);
    People.Add(new Person("Mark", "Moe"), 5);
    People.Add(new Person("Larry", "Loe"), 6);
    People.Add(new Person("Jane", "Doe"), 7);

    foreach (KeyValuePair<Person, int> person in People.OrderBy(i => i.Key.LastName))
    {
        Debug.WriteLine(person.Key.LastName + ", " + person.Key.FirstName + " - Id: " + person.Value.ToString());
    }
}

出力:

Doe, John - Id: 1
Doe, Jane - Id: 7
Loe, Larry - Id: 6
Moe, Mark - Id: 5
Poe, Mary - Id: 2
Roe, Richard - Id: 3
Roe, Anne - Id: 4

この例では、名にThenByを使用することも意味があります。

foreach (KeyValuePair<Person, int> person in People.OrderBy(i => i.Key.LastName).ThenBy(i => i.Key.FirstName))

出力は次のとおりです。

Doe, Jane - Id: 7
Doe, John - Id: 1
Loe, Larry - Id: 6
Moe, Mark - Id: 5
Poe, Mary - Id: 2
Roe, Anne - Id: 4
Roe, Richard - Id: 3

LINQには、OrderByDescendingThenByDescendingが必要な人のためにあります。

1