2

I'm new to lambdas and they seemed fairly straight-forward until I tried to do something more complex. I have this dictionary.

Dictionary<int, int> dict = new Dictionary<int,int>();

of which I want to obtain the key of the key-val pair with the largest value. What I tried is:

dict.Keys.Max(g => dict[g])

The reasoning being that out of the list of Keys, pick that one for which dict[key] is largest. However, this picks the largest value itself, rather than its corresponding key.

2
  • 1
    Well, that's not real code, you're supposed to put something on the left of the 2nd snippet. Make it an assignment to get ahead, the var keyword is nice. Commented Dec 28, 2011 at 23:54
  • 1
    Since you seem to misunderstand me I will specify further: I am looking for the expression which will evaluate to the value of the key from the key-value pair with the largest value of all values in the dictionary. I hope this made it somewhat clearer. Commented Dec 29, 2011 at 0:01

4 Answers 4

6

dict.Keys.OrderByDescending(g => dict[g]).First() will accomplish what you want, but may be inefficient for large dictionaries. MaxBy in John Skeet's MoreLinq will do exactly what you want efficiently.

Sign up to request clarification or add additional context in comments.

Comments

1
var maxValue = dict.Max((maxPair) => maxPair.Value);
var maxPairs = dict.Where((pair) => pair.Value == maxValue);

This will give you a list of all of the pairs that have the maximum value.

If you just want the keys, you can do this afterwards:

var maxKeys = maxPairs.Select((pair) => pair.Key);

7 Comments

Am I correct in assuming that since it avoids the sorting procedures of the other suggested answers it will be considerably faster. Best solution I think so far.
MaxBy will be even faster since this way is forced to iterate over the list of keys twice.
@martixy Yes, the order by is O(n log n), where this pattern is O(n).
@recursive: correct MaxBy will likely be faster, but still on the same order of O(n). Also, I believe this has slightly different behavior than MaxBy?
Actually this is considerably worse performance than sorting. The problem is that the inner call to dict.Max is executed for every element. This is not automatically cached by LINQ. The proper way to do the above is: var maxValue = dict.Max(p => p.Value); var maxPairs = dict.Where(p => p.Value == maxValue);. On my system with 10,000 elements the perf is: this answer=3982ms, OrderBy=113ms, mine=13ms. I would also suggest to answer the question you need to add .Select(p => p.Key) to get the keys for the elements with the largest value rather than the key value pairs.
|
1

I decided to add an answer based on my thoughts on McKay's. This will perform very fast given the standard LINQ methods, provides just the key:

var maxValue = dict.Max(p => p.Value);
var keys = dict.Where(p => p.Value == maxValue).Select(p => p.Key);

Now, if the OP knows that there is always just one key (no duplicate values) then an improvement (very small) would be to use First with this as due to lazy evaluation only the elements up to the one with the maximum value would be evaluated after all were evaluated to first find the maximum value:

var key = dict.Where(p => p.Value == maxValue).First().Key;

1 Comment

You mention that if there are no duplicate values, this is an improvement, but in some cases, this may be what you want anyway. You may not care to have all of the keys that have the maximum value, just any of the keys that have the maximum value. So this solution might be what you want anyway. I just think it's wrong to do that in general. Note that my code (and the first part of your code) only calculates the maximum value, and leaves the finding of the keys to later. Maybe you want the first, maybe you want the count, maybe you want to print them all to the screen. The list is queryable.
0

dict.OrderBy(v => v.Value).Last().Key;

should do it. Basically you are ordering the KeyValuePair by value and picking the last one which will be the maximum. And within the last one you are only interested in the Key.

2 Comments

OP wants the key that corresponds to the greatest value, not the largest value. You may as well have written dict.Values.Max().
An easy mistake to make; I do it all the time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.