C# 从SortedDictionary中查找具有最大值的键?

C# 从SortedDictionary中查找具有最大值的键?,c#,max,sorteddictionary,C#,Max,Sorteddictionary,我有一个SortedDictionary如何找到与最大值关联的键?我必须循环遍历每个KeyValuePair吗?使用可枚举的.OrderByDescending(),然后访问First()返回的内容的Key属性: var dict = new SortedDictionary<string, string> { {"key1", "value3"},

我有一个
SortedDictionary
如何找到与最大值关联的键?我必须循环遍历每个KeyValuePair吗?

使用
可枚举的.OrderByDescending()
,然后访问
First()
返回的内容的
Key
属性:

 var dict = new SortedDictionary<string, string>
                       {
                           {"key1", "value3"},
                           {"key2", "value1"},
                           {"key3", "value2"},
                       };

        var max = dict.OrderByDescending(d => d.Value).First();
        var key = max.Key;
var dict=new SortedDictionary
{
{“key1”,“value3”},
{“key2”,“value1”},
{“key3”,“value2”},
};
var max=dict.OrderByDescending(d=>d.Value).First();
var键=最大键;

获取与最大值关联的键意味着您实际上没有使用SortedDictionary的默认顺序。这是因为SortedDictionar按键排序,而不是按值排序。所以,要想做你想做的事,你可以用老式的LINQ方式:

sortedDict.OrderByDescending(kvp => kvp.Value).First().Key
可以使用中的方法有效地运行此查询

var result =  dictionary.MaxBy(pair => pair.Value).Key;
这只需要迭代数据一次,而不是对值进行排序并获取第一个结果(即
O(n*log(n))

由于只对键进行排序,而不是对值进行排序,因此在执行此查询时,必须至少对每个键对循环一次


另一种选择是有两个SortedDictionary。一个是你已经拥有的字典,另一个是反向字典。对于当前字典中的每个值,可以将其作为键添加到第二个字典中,第二个字典的值将是第一个字典中的键(如果是一对多关系而不是一对一关系,则反向查找的值需要是一个项目列表)。虽然创建第二个字典在编程上“昂贵”(内存比时间多,但仍有一些是两者兼而有之),但一旦创建了第二个字典,您将能够高效地基于值而不是键进行查询。

要获取包含最大值的所有键 有兴趣,必须进行一些数据处理。 实际上,这在C#中是相当舒服的

它可以通过Linq的一些组合来实现

// first of all, group your dictionary by the value you want to have
var groups = dict.GroupBy(d => d.Value);

// then, order those groups by the value
var orderedGroups = groups.OrderBy(g => g.Key);

// after that, you have all the KeyValuePairs that hold the MaxValue here:
var maxKeys = orderedGroups.Last().ToList();

玩得开心

如果
dict
是您的
SortedDictionary
(或任何
idDictionary
)并且您需要与最大值对应的所有键,请首先检查
dict
是否为空(您至少需要一个元素)。那么也许这是可行的:

var max = dict.Values.Max();
var relevantKeys = dict.Where(pair => max.Equals(pair.Value))
    .Select(pair => pair.Key);

也许可以更有效地执行此操作?

所以Max()返回的是一个KeyValuePair,而不仅仅是Max值?我没有投你反对票(尽管我看不出你的答案与Martin Devillers有什么不同)。看起来有人通过了投票,并否决了大多数答案。@用户否,我们的答案没有什么不同,但基本上是同时得到了回答。我不知道到目前为止给出的这些答案是否正确/错误,因为它们都以类似的方式实现了您“可能”需要的功能。这实际上取决于您对
TValue
的约束(如果可能存在重复项、空值等)。LINQ为您提供了大量选项,无论它是否是
SortedDictionary
。您能否澄清一下:您想要最大键吗?
SortedDictionary
按键的大小排序。所以从某种意义上说,这将是“最后”一把钥匙。这是有趣的,如果没有快速的方法得到它!或者你实际上指的是最大值?这是您必须对整个集合进行迭代的内容(可能使用Linq中的
Max
方法。请注意,值不一定是唯一的。您需要所有保存MaxValue的键吗?还是有人会这样做?@JeppeStigNielsen我不需要最大键。我需要最大值的键。了解
TKey
TValue
中的类型也会很有帮助de>SortedDictionary@MareInfinitus任何人都可以。实际上,理想情况下,我会对这两种解决方案都感兴趣。我会编写pair.Value.Equals(max),但是的,它看起来很优雅。我喜欢流畅的代码;)@MareInfinitus我想:有些值是
null
,而
max
null
(虽然我想,如果所有值都是
null
,可能会发生这种情况)。也许我应该说
等于(pair.Value,max)
,即静态
等于
。您是对的,没有想到
null
值…多个,但不是null;)@JeppeStigNielsen为什么要使用
Equal
方法,而不仅仅是简单的Equal比较运算符(=)?这难道不会跳过空值问题吗?您也可以自己实现MaxValue。这只是几行代码:@phoog我假设OP能够复制/粘贴[链接]代码,只用于maxBy并使用它,而不是整个项目(除非他感兴趣)。事实上,它并不是那么多代码。事实上,考虑到LINQtoObjects的所有功能和使用频率,LINQtoObjects的整体代码并不是那么多。感谢迭代器块。+1注意到可能有多个键与最大值关联。