辞書の要素の順序


107

私の質問は、辞書要素の列挙についてです

// Dictionary definition
private Dictionary<string, string> _Dictionary = new Dictionary<string, string>();

// add values using add

_Dictionary.Add("orange", "1");
_Dictionary.Add("apple", "4");
_Dictionary.Add("cucumber", "6");

// add values using []

_Dictionary["banana"] = 7;
_Dictionary["pineapple"] = 7;

// Now lets see how elements are returned by IEnumerator
foreach (KeyValuePair<string, string> kvp in _Dictionary)
{
  Trace.Write(String.Format("{0}={1}", kvp.Key, kvp.Value));
}

列挙される要素はどのような順序でなりますか?順序をアルファベット順にすることはできますか?


回答:


125

辞書の要素の順序は非決定的です。順序の概念は、ハッシュテーブルでは定義されていません。したがって、要素がディクショナリに追加されたのと同じ順序で列挙することに依存しないでください。それは保証されません。

文書からの引用:

列挙のために、ディクショナリ内の各アイテムは、KeyValuePair<TKey, TValue>値とそのキーを表す構造体として扱われます。アイテムが返される順序は定義されていません。



28

要素を順序付けする場合は、OrderedDictionaryを使用します。通常のhastable / dictionaryは、ストレージレイアウトのある意味でのみ注文されます。


10
OrderedDictionaryは、ほとんどの場合間違っています。キーまたは値による順序付けではなく、内部インデックスによる順序付けです。SortedDictionaryは、ユーザーが操作できる方法で注文されたものです(デフォルトキー)
Offler

2
質問はアルファベット順での注文について尋ねています(質問者がキーについて話していると仮定します)。順序付けされた辞書は、ドキュメントを正しく理解していれば、挿入された順序で要素を吐き出します。つまり、アルファベット順ではなく、内部インデックスを使用します。SortedDictionaryは、おそらくユーザーの質問に最適です。
mattpm 2018年

28

いつでも使用できますSortedDictionary。比較演算子が指定されていない限り、ディクショナリはデフォルトでキー順に並べられていることに注意してください。

OrderedDictionaryドキュメントには次のように書かれているので、あなたが何をしたいのかについては疑問があります:

OrderedDictionaryの要素は、SortedDictionaryクラスの要素とは異なり、キーで並べ替えられません。


SortedDictionary<K,V>はバイナリ検索ツリーとして実装されていることに注意することが重要です。これにより、ハッシュテーブルベースのと比較して、操作の時間とスペースの複雑さが異なりDictionary<K,V>ます。ユーザーがO(1)挿入/削除ハッシュテーブル構造を必要とし、キー順で要素を反復処理したい場合、dict.Keys.OrderBy( k => k ).Select( k => dict[k] )代わりに(O(n)スペースとO( n log n )時間を犠牲にして)OrderBy()(内部リストのキーコレクション全体をバッファーする必要がある))。

12

アイテムは、たまたま物理的に辞書に格納されている順序で返されます。これは、ハッシュコードとアイテムが追加された順序によって異なります。したがって、順序はランダムに見えるようになり、実装が変更されても、順序が同じであることに依存することはできません。

列挙するときにアイテムを注文できます。

foreach (KeyValuePair<string, string> kvp in _Dictionary.OrderBy(k => k.Value)) {
  ...
}

フレームワーク2.0では、アイテムを並べ替えるために、まずリストに入れる必要があります。

List<KeyValuePair<string, string>> items = new List<KeyValuePair<string, string>>(_Dictionary);
items.Sort(delegate(KeyValuePair<string, string> x, KeyValuePair<string, string> y) { return x.Value.CompareTo(y.Value); });
foreach (KeyValuePair<string,string> kvp in items) {
  ...
}

11

OrderedDictionaryの場合:

 var _OrderedDictionary = new System.Collections.Specialized.OrderedDictionary();

_OrderedDictionary.Add("testKey1", "testValue1");
_OrderedDictionary.Add("testKey2", "testValue2");
_OrderedDictionary.Add("testKey3", "testValue3");

var k = _OrderedDictionary.Keys.GetEnumerator();
var v = _OrderedDictionary.Values.GetEnumerator();

while (k.MoveNext() && v.MoveNext()) {
    var key = k.Current; var value = v.Current;
}

アイテムは追加された順に返されます。


5

連想配列(別名、ハッシュテーブル)は順序付けされていません。つまり、要素は考えられる任意の方法で順序付けできます。

ただし、配列キー(キーのみ)をフェッチし、それを(ソート関数を介して)アルファベット順に並べてから、それを処理できます。

言語がわからないため、C#のサンプルを提供することはできませんが、これで十分です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.