我可以在选择中返回多个项目吗?例如,我有一个固定装置列表(想想橄榄球(或用于猛拉的足球)固定装置)。每个夹具都包含一个主场和客场球队以及主客场得分。我想得到所有吸引的球队。我想使用像
这样的东西IEnumerable<Team> drew = from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
select fixture.HomeTeam && fixture.AwayTeam;
我知道这种语法不正确,我不知道是否可以这样做。我需要两个查询然后将它们连接起来吗?
编辑:这真的是一个学习的东西,因此以任何特定的方式实现这一点并不重要。基本上,在这个阶段,我想要的是已经绘制的球队列表。一个示例用法可能是对于给定的灯具列表,我可以找到所有绘制的球队,这样我就可以在一个表中更新他们的积分1分(胜利为3,亏损为0)。 < / p>
答案 0 :(得分:33)
101 LINQ Samples,即选择 - 匿名类型1
... select new { HomeTeam = fixture.HomeTeam, AwayTeam = fixture.AwayTeam };
答案 1 :(得分:24)
以下内容将返回IEnumerable&lt; Team&gt;:
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});
此要求通常称为“扁平化”。也就是说,采用&lt;收集&lt;收集物品&gt;&gt;并将其转换为&lt; Collection of Things&gt;。
SelectMany
两个地图(一个团队阵列的固定点)和展平(一系列团队阵列到一系列团队)。它类似于其他语言中的“flatMap”函数,如Java和JavaScript。
可以将Mapping和Flattening分开:
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
枚举两次灯具,因此,根据灯具的实施方式,可能会在两次通话之间更新灯具。例如,如果在调用之间添加了新的绘制夹具,那么可以返回Away团队,但不能返回主页团队。
正如迈克鲍威尔所描述的那样:
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 );
根据灯具的采购/实施方式,可能值得考虑“缓存”绘制的灯具,以避免必须两次枚举灯具。
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));
可以考虑将“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
上找到答案 2 :(得分:22)
我认为你正在寻找如下的Union方法:
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);
答案 3 :(得分:14)
我自己拿出一个与'依赖'相同的版本。
使用查询理解语法:
IEnumerable<Team> drew =
from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
from team in new[]{fixture.AwayTeam, fixture.HomeTeam}
select team;
将lambda与扩展方法一起使用:
IEnumerable<Team> drew =
fixtures.Where(f => f.Played && f.HomeScore == f.AwayScore)
.SelectMany(f => new[]{f.HomeTeam, f.AwayTeam});
编辑:我不知道某个团队是否可能在您的数据库中多次播放和绘制,但如果可能,那么您可能想要使用{{1查询运算符:
Distinct
或:
IEnumerable<Team> drew =
(from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
from team in new[]{fixture.AwayTeam, fixture.HomeTeam}
select team).Distinct();
答案 4 :(得分:6)
或者您可以定义一个类型来保存所有数据:
IEnumerable<TeamCluster> drew = from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
select new TeamCluster {
Team1 = fixture.HomeTeam,
Team2 = fixture.AwayTeam,
Score1 = fixture.HomeScore,
Score2 = fixture.AwayScore
};
class TeamCluster {
public Team Team1 { get; set; }
public Team Team2 { get; set; }
public int Score1 { get; set; }
public int Score2 { get; set; }
}
答案 5 :(得分:5)
编辑:抱歉,误解了原来的问题,所以重写了答案。
您可以使用“SelectMany”运算符执行您想要的操作:
IEnumerable<Team> drew =
(from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
select new List<Team>()
{ HomeTeam = fixture.HomeTeam,
AwayTeam = fixture.AwayTeam
}).SelectMany(team => team);
这将返回一个展平的团队列表。
答案 6 :(得分:1)
我遇到了这个问题,找不到我想要的东西,所以我写了一个小扩展方法,做了我想做的事。
public static IEnumerable<R> MapCombine<M, R>(this IEnumerable<M> origList, params Func<M, R>[] maps)
{
foreach (var item in origList)
foreach (var map in maps)
{
yield return map(item);
}
}
在问题中出现问题后,您可以执行类似这样的操作
var drew = fixtures.Where(fixture => fixture.Played &&
(fixture.HomeScore == fixture.AwayScore))
.MapCombine(f => f.HomeTeam, f => f.AwayTeam);
有趣的是,intellisense对此并不十分满意,你不会在下拉列表的顶部获得lamdba表达式,但是在'=&gt;'之后它很开心。但主要的是编译器很高兴。