下面的代码将返回一个IEnumerable<Team>:
IEnumerable<Team> drew =
from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
from team in new[]{fixture.HomeTeam, fixture.AwayTeam}
select team;
或者,使用流畅的LINQ风格:
IEnumerable<Team> drew =
fixtures
.Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore))
.SelectMany(fixture => new[]{fixture.HomeTeam, fixture.AwayTeam});
展开和 FlatMap
这个要求通常称为“展开”。也就是说,将一个<包含<事物的集合的集合>>转换为一个<事物的集合>。
SelectMany
既映射(将夹具映射到团队数组)又展平(将团队数组序列展平为团队序列)。它类似于其他语言(如Java和JavaScript)中的“flatMap”函数。
可以分离映射和展平:
IEnumerable<Team> drew =
fixtures
.Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore))
// map
.Select(fixture => new[]{fixture.HomeTeam, fixture.AwayTeam})
// flatten
.SelectMany(teams => teams);
其他方法
迭代器块
使用迭代器块也可以实现相同的效果,但我认为这很少是最佳方法:
IEnumerable<Team> Drew(IEnumerable<Fixture> fixtures){
var draws =
fixtures
.Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore));
foreach(var fixture in draws){
yield return fixture.HomeTeam;
yield return fixture.AwayTeam;
}
}
联合
联合(Union)也是一种选项,但有可能会产生不同于上面的结果:
结果的顺序将会不同。所有主场比赛的结果都将先返回,然后是所有客场比赛的结果。
Union
枚举了两次固定比赛(fixtures),因此,取决于固定比赛的实现方式,在调用之间有更新固定比赛的潜力。例如:如果在调用之间添加了新的平局比赛,则可能会返回客队但不返回主队。
正如Mike Powell所描述的那样:
IEnumerable<Team> drew =
( from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
select fixture.HomeTeam
).Union(
from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
select fixture.AwayTeam );
根据 fixtures 的来源/实现方式,考虑“缓存”已经绘制的 fixtures,以避免需要两次枚举 fixtures。
var draws =
( from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
select fixture
).ToList();
IEnumerable<Team> drew =
(from draw in draws select draw.HomeTeam)
.Union(from draw in draws select draw.AwayTeam);
或者使用流畅风格:
var draws =
fixtures
.Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore))
.ToList();
IEnumerable<Team> drew =
draws.Select(fixture => fixture.HomeTeam)
.Union(draws.Select(fixture => fixture.AwayTeam));
修改Fixture类
可以考虑将“ParticipatingTeams”添加到Fixture类中,如下所示:
IEnumerable<Team> drew =
from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
from team in fixture.ParticipatingTeams
select team;
但正如@MattDeKrey指出的那样,这需要更改合同。
代码示例
代码示例可在Repl.it上找到。