我最近发现了高效的代码,包括.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();
}
答案 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)
或使用First
或FirstOrDefault
。
//var sortedList = dictBuff.OrderBy(x => x.Key).ToArray();
var sortedList = dictBuff.OrderBy(x => x.Key).ToList();
应该这样做。