一个有趣的问题。我通常更喜欢使用linq语句来考虑可枚举,但是在这种情况下,我也不会全神贯注。根据我阅读的内容,我可能需要致电ThenBy?下面是正确的foreach实现的示例:
var groupByRepository = flattenedBuilds.GroupBy(x => x.Repository);
foreach (var repositoryBuilds in groupByRepository)
{
var groupByBranch = repositoryBuilds.GroupBy(x => x.SourceBranch);
foreach (var branchBuild in groupByBranch)
{
var versionsOrdered = branchBuild.OrderBy(x => x.Version);
var firstVersion = versionsOrdered.LastOrDefault();
yield return firstVersion;
}
}
基本上,它在存储库上分组,然后按分支分组,以便我可以看到每个版本的最新构建版本。
即使我不喜欢linq的类似SQL的版本,这似乎也是表达这一点的最佳方法。但是,此版本缺少重要的LastOrDefault()调用。
所以问题是此linq(或其他linq)需要做些什么来使其等效。一个目标是可读性,但是在查看我当前的链接与foreach循环时,我很确定foreach在那里赢了。
var result = from build in flattenedBuilds
group build by build.Repository into groupByRepository
from repositories in groupByRepository
group repositories by repositories.SourceBranch into groupBySourceBranch
from sourceBranches in groupBySourceBranch
orderby sourceBranches.Version
select sourceBranches;
return result;
答案 0 :(得分:0)
我会做这样的事情。尽管我不确定我已经完全正确地阅读了该文本,但我已经尝试推断出您拼合数据的结构...但是我认为您的flattenedBuilds
是此类表示的项目列表:>
class FlattenedBuild
{
public string Branch { get; set; }
public string Repository { get; set; }
public int Version { get; set; }
}
因此,我已编写此代码以构建一些示例数据(就我而言,就是List
)
static FlattenedBuild B(string repo, string branch, int version)
{
return new FlattenedBuild
{
Branch = branch,
Repository = repo,
Version = version
};
}
...
var flattenedBuilds = new List<FlattenedBuild>()
{
B("Project X", "master",1),
B("Project X", "master",2),
B("Project X", "master",3),
B("Project X", "develop",2),
B("Project X", "develop",8),
B("Project Y", "master",1),
B("Project Y", "feature_main",1),
B("Project Y", "develop",4),
B("Project Y", "develop",6),
B("Project Y", "develop",12)
};
然后,实际的LINQ内容仅按存储库和分支的所有唯一组合进行分组,然后获得最高的内部版本号。每个独特的组合:
var result = flattenedBuilds
.GroupBy(b => new { b.Repository, b.Branch })
.Select(g => new
{
g.Key.Repository,
g.Key.Branch,
LastBuild = g.OrderByDescending(v => v.Version).FirstOrDefault()?.Version
});
然后简单地检查结果:
foreach (var x in result)
{
Console.WriteLine($"last build for {x.Repository}/{x.Branch} was {x.LastBuild}");
}
输出以下内容:
last build for Project X/master was 3
last build for Project X/develop was 8
last build for Project Y/master was 1
last build for Project Y/feature_main was 1
last build for Project Y/develop was 12
我想 是什么?
答案 1 :(得分:0)
对foreach
代码进行或多或少的直接翻译会产生:
var ans = flattenedBuilds.GroupBy(b => b.Repository)
.SelectMany(b_rg => b_rg.GroupBy(b => b.SourceBranch)
.Select(b_r_sbg => b_r_sbg.OrderByDescending(x => x.Version).First())
);
与OrderByDescending
/ First
相比,我更喜欢OrderBy
/ Last
,因为First
立即返回,效率更高。另外,GroupBy
将仅创建包含至少一个成员的组,因此不需要FirstOrDefault
-您知道至少有一个成员。