web-dev-qa-db-ja.com

辞書内の要素の順序

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

// 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));
}

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

94
Captain Comic

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

引用 ドキュメントから

列挙の目的で、辞書の各アイテムは、値とそのキーを表すKeyValuePair<TKey, TValue>構造体として扱われます。アイテムが返される順序は定義されていません。

112
Darin Dimitrov

そのためには、常に SortedDictionary を使用できます。辞書は、比較子が指定されていない限り、デフォルトでキー順に並べられていることに注意してください。

ドキュメントには次のように書かれているので、あなたが望むものに OrderedDictionary を使用することに懐疑的です。

SortedDictionaryクラスの要素とは異なり、OrderedDictionaryの要素はキーでソートされません。

24
Adrian Carneiro

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

23
Mitch Wheat

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

アイテムを列挙するときに、アイテムを並べ替えることができます。

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) {
  ...
}
12
Guffa

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;
}

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

11
Barton

連想配列(別名、ハッシュテーブル)は順序付けられていません。つまり、要素は考えられる限りの順序で並べることができます。

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

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

4
Tim Čas