Linq 过滤器避免循环
Posted
技术标签:
【中文标题】Linq 过滤器避免循环【英文标题】:Linq filter to avoid a loop 【发布时间】:2019-07-20 21:31:52 【问题描述】:我正在尝试制定一个 LINQ 查询,但不是专业人士,所以无论我尝试什么都行不通。我想过滤列表以从下面的列表中获取电子邮件 ID,其中分数为 0,按团队名称分组。
我尝试这样做的方式是:
-
获取不同团队名称的列表。
遍历每个不同的团队名称并获取得分为 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
我想得到两行:Hawk
和 Amy@gmail.com, Aby@gmail.com
,下一个结果将是 Eagle
和 Blue@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 太酷了,它甚至把函数命名为普通人说话;)Where 和GroupBy。在您的情况下, get 被称为 Select
您的第一种方法可能非常易读且易于维护 :) 但我可以理解使用漂亮 linq 语句的冲动;)
【参考方案1】:
不确定你目前在做什么,但我会这样做
var result = list.Where(p => p.Score == 0)
.Select(p => newp.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);
简单的祝你好运!
【讨论】:
以上是关于Linq 过滤器避免循环的主要内容,如果未能解决你的问题,请参考以下文章