【问题标题】:Linq filter to avoid a loopLinq 过滤器避免循环
【发布时间】:2019-07-20 21:31:52
【问题描述】:

我正在尝试制定一个 LINQ 查询,但不是专业人士,所以无论我尝试什么都行不通。我想过滤列表以从下面的列表中获取电子邮件 ID,其中分数为 0,按团队名称分组。

我尝试这样做的方式是:

  1. 获取不同团队名称的列表。
  2. 遍历每个不同的团队名称并获取得分为 0 的电子邮件 ID。
Team    Name   Score    EmailId  
Hawk    Amy     0       Amy@gmail.com  
Hawk    Aby     0       Aby@gmail.com  
Hawk    Raf     1       Raf@gmail.com  
Hawk    Jay     2       Jay@gmail.com  
Eagle   Blu     0       Blu@gmail.com  
Eagle   Tru     1       Tru@gmail.com  

我想得到两行:HawkAmy@gmail.com, Aby@gmail.com,下一个结果将是 EagleBlue@gmail.com这可以通过 LINQ 一步完成吗?

【问题讨论】:

  • data.Where(x => x.Score == 0).Select(x => new { x.Team, x.EmailId }).GroupBy(x => x.Team)?
  • 为什么要避免循环?
  • 为什么要按团队分组?您最多将获得 2 条记录:Hawk、Eagle。这就是你想要的吗?
  • “想要过滤列表以获取按团队名称分组的分数为 0 的电子邮件 ID。”实际上 linq 太酷了,它甚至把函数命名为普通人说话;)WhereGroupBy。在您的情况下, get 被称为 Select
  • 您的第一种方法可能非常易读且易于维护 :) 但我可以理解使用漂亮 linq 语句的冲动;)

标签: c# asp.net list linq linq-to-objects


【解决方案1】:

不确定你目前在做什么,但我会这样做

var result = list.Where(p => p.Score == 0)
                 .Select(p => new{p.Team, p.EmailId})
                 .GroupBy(p => p.Team)
                 .Distinct();

【讨论】:

    【解决方案2】:

    想要过滤列表以获取按团队名称分组的分数为 0 的电子邮件 ID。

    过滤列表以获取得分为 0 的电子邮件 ID

    var filteredList = list.Where(record => records.Score == 0);
    

    按团队名称分组

    var groupedByTeamName = filteredList.GroupBy(record => record.Team)
    

    如果我没记错的话,这将返回一个IEnumerable<IGrouping<TRecord, TTeam>>IGrouping<T,K> 只是一个带有 Key 属性的列表,其中包含您分组的内容(在这种情况下为团队)。

    您当然可以以级联方式调用它们:

    list.Where(record => records.Score == 0).GroupBy(record => record.Team);
    

    但调试会有点困难,因为您必须选择代码并快速查看句子的各个部分。有时这不起作用。

    【讨论】:

      【解决方案3】:

      想要过滤列表以获取按团队名称分组的分数为 0 的电子邮件 ID。

      这是不是很难说:

      我想要所有没有得分的团队成员的电子邮件?

      将您的数据分组为“球队及其球员及其得分”;只保留分数为零的球队,并提取球员的电子邮件。

      为此,我们使用overload of GroupBy with aKeySelector and aResultSelector

      var emailsOfPlayersInTeamsWithZeroScor = myInput.GroupBy
      
          // keySelector: the team
          .GroupBy(inputItem => inputItem.Team,
      
          // ResultSelector: from every Team with its players and scores
          // make sequences of emails of players and check if there is a score at all
          (team, players) => new
          {
              // not interested in the team
      
              // remember if all scores are zero
              HasOnlyZeroScore = players.All(player.Score == 0),
      
              // remember all emails of the players in the team
              PlayerEmails = players.Select(player => player.Email),
          })
      
          // keep only the items with a zero score
          .Where(team => team.HasOnlyZeroScore)
      
          // and select the lists of emails per team as one big list:
          .SelectMany(team => team.PlayerEmails);
      

      简单的祝你好运!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-14
        相关资源
        最近更新 更多