【问题标题】:How can I replicate this code by using anonymous function (lambda)?如何使用匿名函数 (lambda) 复制此代码?
【发布时间】:2022-01-22 03:21:53
【问题描述】:

我有一个嵌套字典,如下所示:

Dictionary<string, Dictionary<string, int>> users = new Dictionary<string, Dictionary<string, int>>();

第一个字符串是用户的名字,第二个是他参加的比赛,int 是他的分数。一位用户可以参加多项比赛。

我的任务是通过将他的所有分数相加来找到得分最高的用户。现在我使用了这个代码:

foreach (var user in users)
{
    bestUsers.Add(user.Key, 0);
    foreach (var contest in user.Value)
    {
        bestUsers[user.Key] += contest.Value;
    }
}

我想知道如何使用类似这样的匿名函数:

KeyValuePair<string, int> bestUser = users.OrderBy(x => x.Value.Sum());

【问题讨论】:

  • 你能提供一些输入以及它的预期输出吗?

标签: c# .net dictionary lambda


【解决方案1】:

您可以创建一个表示用户结果的类,而不是嵌套字典:

public class UserGameResults
{
    public string Name { get; set; } // the name of the user
    public int TotalScore { get => GameResults.Select(x => x.Value).Sum(); } // total score of all games, will be calculated every time the property is accessed
    public Dictionary<string,int> GameResults { get; set; } = new Dictionary<string,int>(); // key is the name of the game, value is the score
}

如果你使用Dictionary&lt;string,UserGameResults&gt;,你会更容易得到你的结果:

var bestResult = users.OrderByDescending(x => x.Value.TotalScore).FirstOrDefault();

此外,Dictionary&lt;string,UserGameResults&gt;Dictionary&lt;string,Dictionary&lt;string,int&gt;&gt;更能告诉您数据的含义。

【讨论】:

    【解决方案2】:

    对于使用 linq 来获取字典而不是 2 个 foreach 循环的代码重构,您可以使用如下内容:

    users.ToDictionary(u => u.Key, u => u.Value.Select(c => c.Value).Sum());
    

    或者我认为 Sum 采用了选择器 lambda

    users.ToDictionary(u => u.Key, u => u.Value.Sum(c => c.Value));
    

    应该是有效的

    【讨论】:

      【解决方案3】:

      当您需要存储具有与其关联的唯一键的值并且通过该键访问它们对您来说很方便时,您可以使用Dictionary&lt;TKey,TValue&gt;

      我不知道你为什么在这里使用字典。我认为您的用户名不能是唯一的。因此,如果用户名不是唯一的,那么您如何将所有用户存储在字典中。我认为你应该使用列表而不是字典。

      Dictionary<string, Dictionary<string, int>> users = new Dictionary<string, Dictionary<string, int>>()
                  {
                      { "A", new Dictionary<string, int>(){
                              {"sub1", 10},
                              {"sub2", 20},
                              {"sub3", 30}
                          }
                      },
                       { "B", new Dictionary<string, int>(){
                              {"sub1", 10},
                              {"sub2", 40},
                              {"sub3", 30}
                          } 
                      }
                  };
      
      
                  var result = users.OrderBy(x => x.Key).ToDictionary(m => m.Key, m => m.Value.Sum(k => k.Value));
      

      Dictionary 速度非常快,经过了很好的优化,并且在大多数情况下都能提供您需要的性能。但在大多数情况下,这并不重要,键值对链表的性能也足够了。

      【讨论】:

        【解决方案4】:

        试试这个

        var dict = new Dictionary<string, Dictionary<string, int>> {
        
                    { "name1",  new Dictionary<string, int>{ { "A", 2 }, {"B", 3 }}},
                    { "name2",  new Dictionary<string, int>{ { "C", 4 }, {"D", 5 }}}
            };
        
        var scores = dict.Select(d => new { name = d.Key, score = d.Value.Select(x => x.Value).Sum() } )
        .ToList().OrderByDescending (d =>d.score );
        

        分数

            name2   9
            name1   5
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-25
          • 1970-01-01
          • 1970-01-01
          • 2012-09-27
          相关资源
          最近更新 更多