0

最近、.NETの並べ替えを含む生産的なコードを見つけましたDictionary<string,CustomObject>。基本的には、ディクショナリを一時的なディクショナリにコピーしてから、元のディクショナリを.Clear()し、Linq式を介して順序付けられたKeyValuePairsを、CustomObjectsのDateTime値で挿入します。

私はこのコードが機能しないことを期待し、辞書(およびHashSet)をソートできないことを期待して、すでにそれを削除していました。次に、次のテストコードを記述しました。これは、驚いたことに、foreachループを繰り返したときに、辞書からの並べ替えられた出力を示していました。

これは、現在の実装ではランダム効果でありDictionary<TKey, TValue>、現在の場合は機能する可能性がありますが、.NETの別の実装では失敗しますか?それとも、.NET辞書で使用される標準機能ですか?

私はまだ生産的なコードに欠陥があると考えていますが、機能しています。注文が並べ替えルーチンを見つけた場所以外の場所で使用されている場合、長いテストを必要として、それを削除する必要がありますか、それともそのままにしておいても安全ですか?

これが私のテストコードです:

static void Main(string[] args)
{
    var rnd = new Random();
    var dict = new Dictionary<int, string>();
    for (int i = 0 ; i < 10 ; i++)
    {
        int rndValue;
        do
        {
            rndValue = rnd.Next(100);
        }
        while (dict.ContainsKey(rndValue));

        dict.Add(rndValue, "MyValue#" + i);
    }

    foreach (KeyValuePair<int, string> pair in dict)
    {
        Console.WriteLine("Key: " + pair.Key + ", Value: " + pair.Value);
    }

    Console.Write("Enter...");
    Console.ReadLine();

    var dictBuff = dict.ToDictionary(p => p.Key, p => p.Value);
    dict.Clear();

    var sortdict = from pair in dictBuff orderby pair.Key ascending select pair;

    foreach (KeyValuePair<int, string> pair in sortdict)
    {
        dict.Add(pair.Key, pair.Value);
    }

    Console.WriteLine("'Sorted' Dictionary:");

    foreach (KeyValuePair<int, string> pair in dict)
    {
        Console.WriteLine("Key: " + pair.Key + ", Value: " + pair.Value);
    }

    Console.Write("Enter...");
    Console.ReadLine();

}
4

2 に答える 2

5

これは現在の実装に基づいていますが、実装間で保証されているわけではありません。SortedDictionaryを使用しない限り、または最後のforeachループを変更してdict.OrderBy(pair => pair.Key)を反復処理しない限り、順序は保証されません。

ドキュメントから(備考セクション)

列挙の目的で、ディクショナリ内の各アイテムは、値とそのキーを表すKeyValuePair構造として扱われます。アイテムが返される順序は未定義です。

于 2012-10-16T16:46:32.073 に答える
1

ディクショナリは、各要素の識別子を含む単純なリストであるため、要素は配置された順序で返されます。ただし、たとえば、要素を削除して再度挿入するためだけに要素を削除しないという保証はありません。また後ろに。

Dictionary をソートしたままにしたい場合は、 SortedDictionaryクラスを使用することをお勧めします。

または、順序付けが必要なときにいつでも LINQ に辞書を並べ替えさせます。

ちなみに、このコード部分は次のように置き換えることができます。

    var sortdict = from pair in dictBuff orderby pair.Key ascending select pair;

    foreach (KeyValuePair<int, string> pair in sortdict)
    {
        dict.Add(pair.Key, pair.Value);
    }

    foreach (var pair in dictBuff.OrderBy(x => x.Key))
    {
        //dict.Add(pair.Key, pair.Value);
        //meaningful code here
    }

アップデート

SortedDictionary を使用する代わりに、別のことを行うことができます。List<KeyValuePair<int, string>>の代わりに または Array を使用しDictionary<int, string>ます。反復時の使用法はまったく同じですが、インデクサーのように使用することはできませんlist[someItem]list.Single(x => x.Key == someItem)次に、 or を使用するか、代わりに orFirstを使用する必要がありますFirstOrDefault

//var sortedList = dictBuff.OrderBy(x => x.Key).ToArray();
var sortedList = dictBuff.OrderBy(x => x.Key).ToList();

トリックを行う必要があります。

于 2012-10-16T16:52:02.237 に答える