Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the first sorted element with LINQ? (C#)

First, have a look at this code:

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;
}

This code, basically prints the value of the entry in the dictionary with the highest value. I'd like to accomplish this without using a "broken" foreach loop. How might I do that?

like image 558
Georges Oates Larsen Avatar asked Dec 22 '22 03:12

Georges Oates Larsen


1 Answers

Well, you could do:

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

This is not only more concise, but also doesn't require sorting the dictionary out-of-place first (which is what starting an enumeration onOrderByDescending does), so is more efficient in both time and space.

If you need the key as well, you can use a MaxBy operator (such as from moreLinq) as follows:

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

It is possible to accomplish this with standard LINQ to Objects in O(n) time and O(1) space with the Aggregate operator, but it's quite ugly:

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);
}
like image 113
Ani Avatar answered Dec 24 '22 02:12

Ani