私はDictionary
がKeyValuePair
を追加されたのと同じ順序で列挙する方法を探していました。さて、 Dictionary's documentation は次のことを明確に述べています:
列挙の目的で、辞書の各アイテムは、値とそのキーを表す
KeyValuePair<TKey, TValue>
構造体として扱われます。アイテムが返される順序は定義されていません。
必要なのはOrderedDictionary
であることがわかりましたが、私は懐疑的であるため、自分で試してみることにしました。
OrderedDictionary od = new OrderedDictionary();
Dictionary<String, String> d = new Dictionary<String, String>();
for (int i = 0; i < 10; i++)
{
od.Add("key" + i, "value" + i);
d.Add("key" + i, "value" + i);
}
System.Console.WriteLine("OrderedDictionary");
foreach (DictionaryEntry de in od) {
System.Console.WriteLine(de.Key + ", " + de.Value);
}
System.Console.WriteLine("Dictionary");
foreach (var tmp in d) {
System.Console.WriteLine(tmp.Key + ", " + tmp.Value);
}
出力:
OrderedDictionary
key0, value0
key1, value1
key2, value2
...
Dictionary
key0, value0
key1, value1
key2, value2
...
ご覧のとおり、両方とも注文されており、次の2つの疑問が生じます。
どの場合にDictionary
は、値が追加される順序とは異なる順序を与えますか?最初のforeach
ループは、KeyValuePair
を同じ順序で取得することを保証しますか、それともインデックスを使用する必要がありますか?
それは間違っている。辞書に値を順番に挿入するだけでなく、いくつかの要素を削除して、この後に順序がどのように変化したかを確認する必要があります。次のコードはこれを示しています。
OrderedDictionary od = new OrderedDictionary();
Dictionary<String, String> d = new Dictionary<String, String>();
Random r = new Random();
for (int i = 0; i < 10; i++)
{
od.Add("key" + i, "value" + i);
d.Add("key" + i, "value" + i);
if (i % 3 == 0)
{
od.Remove("key" + r.Next(d.Count));
d.Remove("key" + r.Next(d.Count));
}
}
System.Console.WriteLine("OrderedDictionary");
foreach (DictionaryEntry de in od) {
System.Console.WriteLine(de.Key + ", " +de.Value);
}
System.Console.WriteLine("Dictionary");
foreach (var tmp in d) {
System.Console.WriteLine(tmp.Key + ", " + tmp.Value);
}
次のようなものを出力します(OrderedDictionaryは常に注文されます):
OrderedDictionary
key3, value3
key5, value5
key6, value6
key7, value7
key8, value8
key9, value9
Dictionary
key7, value7
key4, value4
key3, value3
key5, value5
key6, value6
key8, value8
key9, value9