如何获取 C# 字典中第一个最大值的键?

How to get the key of the first max value in a C# Dictionary?

我想获取 dictionary {'a' : 1, 'b' : 2, 'c' : 2} 中最大值的键。在这种情况下,我希望它 return 'b' 但使用

weight.Aggregate((l, r) => l.Value > r.Value ? l : r).Key;

return 是最后一个最大值,即 'c'

  1. 有没有办法return我的字典中第一个最大值的键? =>'b'
  2. 此外,是否可以 return 最大绑定值的键数组? => new char[]{'b', 'c'}
  3. 我应该改用哪种键值数据结构?

编辑: 由于它在评论中引起了不小的轰动,我指的是插入顺序方面的第一个最大值。

(为了建议)

受到 this answer 的启发,我将建议一种方法,您可以创建自己的继承自 List<KeyValuePair<char, int>> 的类型(从而保留插入顺序),并隐藏 base.Add() 方法使用一种方法确保只有具有唯一 key 的条目才会添加到您的列表中。

如果您可以一项一项地添加您的项目,并且如果 向您的列表添加 项是您打算更改列表的唯一方式,那么这对您的特定用例非常有效内容。如果有机会,您可能需要例如从您的列表中删除项目,实施需要扩展以涵盖该项目。

另外值得一提的是:此实现让尝试向列表中添加带有 non-unique 键的条目的事件静默通过。没有尖叫声;该条目根本没有添加。

实施:

public class UniqueKeyKvpList : List<KeyValuePair<char, int>>
{
    private readonly HashSet<char> _keys = new HashSet<char>();

    // Hiding base method List<KeyValuePair<char, int>>.Add()
    public new void Add(KeyValuePair<char, int> kvp) => Add(kvp.Key, kvp.Value);
    
    // Simpler .Add() method; imitates Dictionary.Add() in usage
    public void Add(char key, int value) => AddIfUniqueKey(key, value);

    private void AddIfUniqueKey(char key, int value)
    {
        if (!_keys.Contains(key))
        {
            _keys.Add(key);
            base.Add(new KeyValuePair<char, int>(key, value));
        }
    }
}

用法:

var myKvpList = new UniqueKeyKvpList();

myKvpList.Add('a', 1);
myKvpList.Add('a', 2); // will not be added (duplicate key)
myKvpList.Add('b', 3);

填充列表后,您可以得到具有最大值的所有字符,如下所示:

.Net 6(由于使用了.MaxBy()

char[] charsWithMaxValue = myKvpList
    .GroupBy(kvp => kvp.Value)
    .MaxBy(gr => gr.Key) // Group key is the kvp value
    .Select(kvp => kvp.Key)
    .ToArray();

<.Net 6

char[] charsWithMaxValue = myKvpList
    .GroupBy(kvp => kvp.Value)
    .OrderByDescending(gr => gr.Key) // Group key is the kvp value
    .First()
    .Select(kvp => kvp.Key)
    .ToArray();

具有最大值的第一个字符将是

char firstCharWithMaxValue = charsWithMaxValue.First();

或者,如果不需要计算charsWithMaxValuefirstCharWithMaxValue可以直接计算如下:

.网6

char firstCharWithMaxValue = myKvpList
    .MaxBy(kvp => kvp.Value)
    .Key;

<.Net 6

char firstCharWithMaxValue = myKvpList
    .OrderByDescending(kvp => kvp.Value)
    .First()
    .Key;

示例 fiddle here.