如何使用匿名函数 (lambda) 复制此代码?

Posted

技术标签:

【中文标题】如何使用匿名函数 (lambda) 复制此代码?【英文标题】:How can I replicate this code by using anonymous function (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());

【问题讨论】:

你能提供一些输入以及它的预期输出吗? 【参考方案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

【讨论】:

以上是关于如何使用匿名函数 (lambda) 复制此代码?的主要内容,如果未能解决你的问题,请参考以下文章

匿名方法

Lambda 表达式与匿名内部类

python基础——匿名函数及递归函数

python学习十五天

Lambda 表达式和函数式接口的关系

lambda 函数有啥用? [复制]