如何从字典中获取最大值?

57

我有

Dictionary<Guid, DateTime> d = new Dictionary<Guid, DateTime>();

如何获取具有MAX值的Guid


3
可能是重复的问题:获取字母数字值的最大值 - M.Babcock
在向SO提问之前,请尝试自己进行研究。 - M.Babcock
1
由于“GUID”代表“全局唯一标识符”,因此你想要“最大”值似乎非常奇怪。使用GUID是因为它的唯一性;我无法想象在现实世界中有任何应用程序需要将它们视为有序。 - jpmc26
我认为jpmc26先生完全误解了重点。例如,假设我有一个var fooDict = new Dictionary<string, int>();,其中字符串值是GUID,我想知道哪个kvp具有最高的int值(使用MoreLinq):var biggestIntKey = fooDict.MaxBy(kvp => kvp.Value).Key; var biggestInt = fooDict[biggestIntKey]。我认为几乎任何阅读SO的人都知道GUID是什么。这并没有帮助。 - GDB
这里有完全相同的问题:链接 - RBT
8个回答

130

既然这是被接受的答案,我将尝试涵盖问题的每一个可能的意思:

var dict = 
    new Dictionary<string, int> 
    { 
        ["b"] = 3, 
        ["a"] = 4 
    };

// greatest key
var maxKey = dict.Keys.Max(); // "b"

// greatest value
var maxValue = dict.Values.Max(); // 4

// key of the greatest value
// 4 is the greatest value, and its key is "a", so "a" is the answer.
var keyOfMaxValue = 
    dict.Aggregate((x, y) => x.Value > y.Value ? x : y).Key; // "a"
注意:问题的键类型是 System.Guid。询问“最大的GUID是什么”可能没有意义,因为它们只是想要成为唯一值,而不代表任何可排序的概念。尽管如此,上面的代码将适用于支持 > 运算符的任何类型,在这里选择 stringint 是为了简洁明了。

11
但他要求的是具有最大值的密钥,这只会给我们最大的密钥,因此是错误的东西。 - robbpriestley
如果有人想要获得最大值,他们可以使用 d.Values.Max(); - John G

53

这个很好用。它将返回最大日期的 GUID。

Dictionary<Guid, DateTime> d = new Dictionary<Guid, DateTime>(); 
var guidForMaxDate = d.FirstOrDefault(x => x.Value == d.Values.Max()).Key;

5
不错,但我建议提前将 d.Values.Max() 存储在一个变量中,否则它可能会在每次迭代中重复搜索 Max()。 - Nyerguds

12
            var maxGuid = Guid.Empty;
            var maxDateTime = DateTime.MinValue;
            foreach (var kvp in d)
            {
                if (kvp.Value > maxDateTime)
                {
                    maxGuid = kvp.Key;
                    maxDateTime = kvp.Value;
                }
            }
            Console.WriteLine("Guid of max date is: " + maxGuid.ToString());

1
重新阅读问题,我认为这是正确的解释,并且是唯一能给出正确结果的答案(虽然我怀疑可以用LINQ缩短代码,但它不会比这个显式循环更快)。 - Ben Voigt
1
@BenVoigt 明确的循环在清晰度方面是最好的选择。这里有另一篇帖子链接,其中有一些非常好的答案。该帖子中被接受的答案声称使用LINQ进行单次扫描。 - RBT

6

首先对您的数据进行排序可能是一个解决方案。

var maxGuid = d.OrderByDescending(x => x.Value).FirstOrDefault().Key;

将整个列表排序与仅返回最高值相比有点昂贵。 - Bill Tarbell
1
OrderByDescending返回一个IOrderedEnumerable(它是一个IEnumerable,提供了更多的排序选项,比如ThenBy或ThenByDescending)。这段代码只会遍历一次数据,获取最高值,然后输出第一个。它不会重新排序整个列表,除非你将其实例化并存储在某个地方,比如使用.ToArray()存储在变量中。FirstOrDefault仅仅是在存在时取第一个项目,并不迭代所有值。它与其他答案有何不同?你知道linq .Max或.MaxBy扩展是如何工作的吗? - felixperreault

5

Guid实现了IComparable接口,因此:

d.Keys.Max()

此外,为什么有人想这样做并不清楚...

3

通过在字典上使用LINQ。

var MaximumValue = dict.FirstOrDefault(x => x.Value.Equals(dict.Values.Max()));

3

那个被接受的答案对我没用。但是以下代码(使用MoreLinq)解决了问题:

var fooDict = new Dictionary<string, int>();
var keyForBiggest = fooDict.MaxBy(kvp => kvp.Value).Key;
var biggestInt = fooDict[keyForBiggest];

0

另一种方法可以帮助获取单个KeyValuePair。

KeyValuePair<char, int> GuidKeyPair = guidDict.FirstOrDefault( MaxGuid => MaxGuid.Value == guidDict.Values.Max());

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