2011-12-28 3 views
2

Я новичок в лямбдах, и они казались довольно прямолинейными, пока я не попытался сделать что-то более сложное. У меня есть этот словарь.Понимание лямбда-выражений в C#

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

, из которого я хочу получить ключ от пары ключ-вал с наибольшим значением. То, что я попытался это:

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

Аргументация в том, что из списка ключей, выберите тот, для которого один Сыроватского [ключ] является наибольшим. Однако это выбирает самое большое значение, а не соответствующий ему ключ.

+1

Ну, это не реальный код, вы» он должен положить что-то слева от второго фрагмента. Сделайте это заданием, чтобы продолжить, ключевое слово * var * - это хорошо. –

+1

Поскольку вы, кажется, неправильно поняли меня, я уточню: я ищу выражение, которое будет оценивать значение ключа из пары ключ-значение с наибольшим значением всех значений в словаре. Надеюсь, что это несколько яснее. – martixy

ответ

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

Это даст вам список всех пар, которые имеют максимальное значение.

Если вы просто хотите ключи, вы можете сделать это позже:

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

Правильно ли я предполагаю, что, поскольку он избегает процедур сортировки других предложенных ответов, он будет значительно быстрее. Лучшее решение, которое я думаю до сих пор. – martixy

+0

'MaxBy' будет еще быстрее, так как этот способ вынужден дважды перебирать список ключей. – recursive

+0

@martixy Да, порядок по O (n log n), где этот шаблон равен O (n). – McKay

0

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

должны это сделать. В основном вы заказываете KeyValuePair по значению и выбираете последний, который будет максимальным. И в последнем вы интересуетесь только ключом.

+2

OP хочет ключ, который соответствует наибольшему значению, а не самому большому значению. Вы также можете написать 'dict.Values.Max()'. –

+0

@EdS. Ответили слишком рано .. исправлено сейчас –

+0

Простая ошибка; Я делаю это все время. –

6

dict.Keys.OrderByDescending(g => dict[g]).First() выполнит то, что вы хотите, но может быть неэффективным для больших словарей. MaxBy в приложении MoreLinq от John Skeet сделает именно то, что вы хотите эффективно.

1

Я решил добавить ответ, основанный на моих мыслях на Маккей. Это будет работать очень быстро, учитывая стандартные методы LINQ, обеспечивает только ключ:

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

Теперь, если OP знает, что всегда есть только один ключ (без повторяющихся значений), то улучшение (очень мало) будет использовать First с этим, как из-за ленивых вычислений только те элементы, вплоть до того, с максимальным значением будет оцениваться после того, как все были оценены сначала найти максимальное значение:

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

Вы отмечаете, что если нет повторяющихся значений, это улучшение, но в некоторых случаях это может быть то, что вы хотите в любом случае. Возможно, вам не нужны все ключи с максимальным значением, только любой из ключей, которые имеют максимальное значение. Таким образом, это решение может быть тем, что вы хотите в любом случае. Я просто думаю, что это неправильно делать в целом. Обратите внимание, что мой код (и первая часть вашего кода) вычисляет только максимальное значение и оставляет поиск ключей позже. Возможно, вы хотите, чтобы первый, может быть, вам нужен граф, возможно, вы хотите распечатать их все на экране. Список доступен для запроса. – McKay