排序.NET字典 - 错误或不支持的功能?

时间:2012-10-16 16:43:42

标签: .net sorting dictionary

我最近发现了高效的代码,包括.NET Dictionary<string,CustomObject>的排序。它基本上是将字典复制到临时字典,然后.Clear()原始并插入通过Linq表达式排序的KeyValuePairs,通过CustomObjects中的DateTime值。

我希望这段代码不起作用,并且已经删除它,期望无法对字典(以及HashSet)进行排序。然后我编写了下面的测试代码,令我惊讶的是,当使用foreach循环迭代时,它显示了字典中的排序输出。

这是Dictionary<TKey, TValue>当前实现中的随机效应,可能在当前情况下有效,但在另一个.NET实现中失败了吗?或者它是.NET Dictionaries中使用的标准功能吗?

我仍然认为生产代码有缺陷,但仍在工作。我是否应该将其删除,需要进行长时间的测试,如果订单是在我找到分拣程序的地方使用的地方,或者是否可以安全地保留原样?

这是我的测试代码:

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();

}

2 个答案:

答案 0 :(得分:5)

它基于当前的实现,但不保证跨实现。除非您使用SortedDictionary,或者您更改了上一个foreach循环以迭代dict.OrderBy(pair =&gt; pair.Key),否则无法保证订单。

From the documentation (Remarks section)

  

出于枚举的目的,字典中的每个项都被视为表示值及其键的KeyValuePair结构。 未定义项目的退货顺序。

答案 1 :(得分: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>>或数组而不是Dictionary<int, string>。迭代时的用法完全相同,但您将无法使用list[someItem]之类的索引器。然后,您需要list.Single(x => x.Key == someItem)或使用FirstFirstOrDefault

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

应该这样做。