如何在C#中订购字典?

7
我有一个数字列表,我想创建另一个列表,其中包含出现在开头最多和结尾最少的数字。
所以我遍历了列表,并检查数字x是否在字典中。如果不在,则将键x和值1添加到字典中。如果存在,则将值更改为原来的值加一。
现在我想按顺序排列字典,以便我可以创建一个列表,其中出现最多的数字在开头,最少的数字在结尾。
如何在C#中做到这一点? ps. 运行时间非常重要。
4个回答

11

看起来你有一个Dictionary<int, int>,其中键表示列表中的某个整数,对应的值表示该整数出现的次数。你想按出现频率降序排序键,那么可以这样说:

// dict is Dictionary<int, int>
var ordered = dict.Keys.OrderByDescending(k => dict[k]).ToList();

现在,根据你的描述,你开始使用了一个 List<int>,其中包含了你想要计数并按照计数排序的值。你可以通过 LINQ 快速地完成这个操作:

// list is IEnumerable<int> (e.g., List<int>)
var ordered = list.GroupBy(n => n)
                  .OrderByDescending(g => g.Count())
                  .Select(g => g.Key)
                  .ToList();

或者使用查询语法:

var ordered = (from n in list
               group n by n into g
               orderby g.Count() descending
               select g.Key).ToList();

现在,如果你需要中间的字典,你可以这样说

var dict = list.GroupBy(n => n)
               .ToDictionary(g => g.Key, g => g.Count());
var ordered = dict.Keys.OrderByDescending(k => dict[k]).ToList();

1
后者并不完全相同。它创建的是一个匿名对象列表,而不是字典。这可能已经足够了,但如果需要字典而不仅仅是方便,我会使用ToDictionary。 - tvanfosson
我运行它时出现了异常System.StackOverflowException,这是怎么回事? - Daniel
你用什么输入运行了什么,然后出现了 StackOverflowException - jason

1
使用IEnumerable()上的GroupBy扩展来对数字进行分组并提取每个数字的计数。这将在一个语句中创建字典并对其进行排序。
var ordered = list.GroupBy( l => l )
                  .OrderByDescending( g => g.Count() )
                  .ToDictionary( g => g.Key, g.Count() );

0
    List<KeyValuePair<type, type>> listEquivalent = 
new List<KeyValuePair<type, type>>(dictionary);    

    listEquivalent.Sort((first,second) =>
            {
                return first.Value.CompareTo(second.Value);
            });

可能是这样吧?

编辑:感谢Jason提醒我遗漏了什么


字典上没有 Sort 方法。 - jason
我错过了实例化List的那个部分,用字典对象。非常抱歉。不过从上面来看LINQ似乎更好!感谢Jason的提醒!List<KeyValuePair<type, type>> myList = new List<KeyValuePair<type, type>>(dictionary); - Aggelos Biboudis

0

您也可以考虑使用SortedDictionary。

它在插入时根据键对项目进行排序。 了解更多..


他希望将字典键按照它们对应的值排序,这与SortedDictionary所提供的方式有很大区别。 - jason

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