按键和列表内的值对Dictionary<int, List<int>>进行排序

6
假设我们有一个

标签。

var dictionary= new Dictionary<int, IList<int>>();

我希望输出一个排序后的版本,首先按键排序,然后按列表内的值排序。
例如:
1   2, 1, 6
5   2, 1
2   1, 3

成为:

变成

1    1, 2, 6
2    1, 3
5    1, 2

我尝试在foreach内部执行此操作,但显然这是一个不好的想法,因为你正在迭代的内容被改变了。


1
我想要的是一个排序后的版本 - 你希望它以什么形式呈现?作为输出还是作为新的集合? - H H
4个回答

12

试试这个:

    // Creating test data
    var dictionary = new Dictionary<int, IList<int>>
    {
        { 1, new List<int> { 2, 1, 6 } },
        { 5, new List<int> { 2, 1 } },
        { 2, new List<int> { 2, 3 } }
    };

    // Ordering as requested
    dictionary = dictionary
        .OrderBy(d => d.Key)
        .ToDictionary(
            d => d.Key,
            d => (IList<int>)d.Value.OrderBy(v => v).ToList()
        );

    // Displaying the results
    foreach(var kv in dictionary)
    {
        Console.Write("\n{0}", kv.Key);
        foreach (var li in kv.Value)
        {
            Console.Write("\t{0}", li);
        }
    }

这里有两个错误。一,通过将它们放回字典中,你又破坏了他的首选顺序。二,你不能将IOrderedEnumerable<T>强制转换为IList<T> - nawfal
我们确实错过了 ToList 调用。但是顺序仍然被保留了。 - Schiavini
但是,最后调用ToDictionary,你将项目放回了一个无序集合中。这个“工作”的部分是巧合的,它没有被记录下来。实现可能会改变。要记住的是,字典本质上是一个无序集合参见 - nawfal

3
您可以使用LINQ按以下方式对字典内容进行排序:
        var dictionary = new Dictionary<int, IList<int>>();
        var orderedItems = dictionary
                               .OrderBy(pair => pair.Key)
                               .Select(new {
                                        Key = pair.Key, 
                                        Value = pair.Value.OrderBy(i => i)});

当然,这样做相当丑陋。此时更好的选择是使用LINQ语法。
            var orderedItems =from pair in dictionary
                  orderby pair.Key
                  let values = pair.Value.OrderBy(i => i)
                  select new { Key = pair.Key, Value = values };

如果需要将结果IEnumerable用作列表或数组,可以使用ToList或ToArray创建一个。但在大多数情况下,您可以直接使用IEnumerable。

失败!当转换为字典时,顺序将会丢失。 - leppie
糟糕,我直接从工作代码中复制了这段内容。现在正在更改。 - Panagiotis Kanavos

3

Dictionary是无序的。如果要对字典进行排序,可以使用OrderedDictionary

要对列表进行排序,可以使用List<T>.OrderBy()


1
-1:未回答问题,请再次阅读。OP并不想对字典进行排序,他/她只想输出已排序的内容。 - leppie
@leppie 我再读了一遍。依然,楼主明确表示他/她想要一个“排序后的版本”。一个字典的排序版本就是...好吧,你猜猜看。无论如何,感谢你的踩。 - Dennis Traub

0
你可以遍历字典项并分别对每个列表进行排序。代码如下:
SortDictionary(dictionary);
之后:
foreach (System.Collections.Generic.KeyValuePair<int,IList<int>> list in dictionary)
        { 
            SortDictionary( list.Value)
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接