使用LINQ获取第一个排序后的元素?(C#)

4

首先,看一下这段代码:

Dictionary<int,int> dict = Dictionary<int,int>();
dict[3] = 1;
dict[2] = 2;
dict[1] = 3;

foreach(KeyValuePair<int,int> item in dict.OrderByDescending(p => p.Value))
{
    print(item.Value);
    break;
}

这段代码基本上会打印字典中值最高的条目。我希望在不使用“损坏”的foreach循环的情况下完成这个任务。有什么方法可以做到呢?

2个回答

10

好的,你可以这样做:

if(dict.Any())
   print(dict.Values.Max());

这种方法不仅更加简洁,而且不需要事先对字典进行排序(这是使用OrderByDescending开始枚举时发生的),因此在时间和空间上都更加高效。

如果你还需要键值,可以使用MaxBy运算符(比如来自于moreLinq库)如下所示:

if(dict.Any())
{
    var bestKvp = dict.MaxBy(kvp => kvp.Value);
    Console.WriteLine("Key = {0}, Value = {1}", bestKvp.Key, bestKvp.Value);
}

使用标准的LINQ to Objects和聚合操作符,可以在O(n)时间和O(1)空间内实现,但这相当丑陋:

if(dict.Any())
{
    var bestKvp = dict.Aggregate((bestSoFar, next) => bestSoFar.Value > next.Value ? bestSoFar : next );
    Console.WriteLine("Key = {0}, Value = {1}", bestKvp.Key, bestKvp.Value);
}

好的!这似乎比使用LINQ简单得多,谢谢!不过,有一件事是,我也需要获取键。这可行吗? - Georges Oates Larsen
3
实际上,你所看到的很多内容都属于 LINQ。更准确地说,它是 IEnumerable<T> 接口的扩展方法。 - Robert Harvey

1

大多数情况下,我对Ani的回答感到满意。但是,我想指出First<T>()Last<T>() LINQ函数。

var value = dict.OrderByAscending(pair => pair.Value).First();

很抱歉我不能直接评论,我是一个新成员。然而,你应该使用Ani的答案,因为他正确地说他的方法更快。


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