Хороший способ получить ключ самого высокого значения Словаря в C#

Я пытаюсь вложить ключ максимального значения Dictionary<string, double> results.

Это - то, что я имею до сих пор:

double max = results.Max(kvp => kvp.Value);
return results.Where(kvp => kvp.Value == max).Select(kvp => kvp.Key).First();

Однако, так как это кажется немного неэффективным, я задавался вопросом, был ли лучший способ сделать это.

69
задан Arda Xi 10 May 2010 в 19:25
поделиться

4 ответа

Я думаю, что это наиболее читаемый ответ O (n) с использованием стандартного LINQ.

var max = results.Aggregate((l, r) => l.Value > r.Value ? l : r).Key;

править: объяснение CoffeeAddict

Aggregate - это имя LINQ для общеизвестной функциональной концепции Fold

Он перебирает каждый элемент набора и применяет любую предоставленную вами функцию. {{1 }} Здесь предоставляемая мною функция представляет собой функцию сравнения, которая возвращает большее значение. Во время цикла Aggregate запоминает результат, возвращенный при последнем вызове моей функции. Он передает это в мою функцию сравнения как переменную l . Переменная r - это текущий выбранный элемент.

Таким образом, после того, как агрегат прошел цикл по всему набору, он возвращает результат самого последнего вызова моей функции сравнения. Затем я прочитал член .Key из него, потому что я знаю, что это словарная статья

Вот другой способ взглянуть на это [я не гарантирую, что это компилируется;)]

var l = results[0];
for(int i=1; i<results.Count(); ++i)
{
    var r = results[i];
    if(r.Value > l.Value)
        l = r;        
}
var max = l.Key;
125
ответ дан 24 November 2019 в 13:41
поделиться

Возможно, это не лучший вариант для LINQ. Я вижу 2 полных сканирования словаря с помощью решения LINQ (1 для получения максимального значения, затем еще одного для поиска kvp для возврата строки.

Вы можете сделать это за 1 проход с помощью «старомодного» foreach:


KeyValuePair<string, double> max = new KeyValuePair<string, double>(); 
foreach (var kvp in results)
{
  if (kvp.Value > max.Value)
    max = kvp;
}
return max.Key;

11
ответ дан 24 November 2019 в 13:41
поделиться

Это быстрый метод. Это O(n), что является оптимальным. Единственная проблема, которую я вижу, это то, что итерации по словарю выполняются дважды, а не один раз.

Вы можете сделать итерацию по словарю один раз, используя MaxBy из morelinq.

results.MaxBy(kvp => kvp.Value).Key;
7
ответ дан 24 November 2019 в 13:41
поделиться

Я думаю, что, используя стандартные библиотеки LINQ, это настолько быстро, насколько это возможно.

-4
ответ дан 24 November 2019 в 13:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: