web-dev-qa-db-ja.com

OrderedDictionaryとDictionary

私はDictionaryKeyValuePairを追加されたのと同じ順序で列挙する方法を探していました。さて、 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を同じ順序で取得することを保証しますか、それともインデックスを使用する必要がありますか?

51
DeadlyJesus

それは間違っている。辞書に値を順番に挿入するだけでなく、いくつかの要素を削除して、この後に順序がどのように変化したかを確認する必要があります。次のコードはこれを示しています。

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
61
Ilya Ivanov