gpt4 book ai didi

c# - 是否可以将其作为单个高效的 LINQ 查询来执行?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:40:27 24 4
gpt4 key购买 nike

我有一个类

public class Foo
{
public string X;
public string Y;
public int Z;
}

我想要实现的查询是,给定一个 IEnumerable<Foo>称为 foos ,

"Group by X, then by Y, and choose the the largest subgroup from each supergroup; if there is a tie, choose the one with the largest Z."

换句话说,一个不太紧凑的解决方案看起来像

var outer = foos.GroupBy(f => f.X);
foreach(var g1 in outer)
{
var inner = g1.GroupBy(g2 => g2.Y);
int maxCount = inner.Max(g3 => g3.Count());
var winners = inner.Where(g4 => g4.Count() == maxCount));
if(winners.Count() > 1)
{
yield return winners.MaxBy(w => w.Z);
}
else
{
yield return winners.Single();
}
}

一个不太有效的解决方案就像

from foo in foos
group foo by new { foo.X, foo.Y } into g
order by g.Key.X, g.Count(), g.Max(f => f.Z)
. . . // can't figure the rest out

但理想情况下,我希望既紧凑又高效。

最佳答案

您过多地重复使用枚举,这会导致再次执行整个枚举,这在某些情况下会导致性能显着下降。

你的代码不是很紧凑,可以简化成这样。

foreach (var byX in foos.GroupBy(f => f.X))
{
yield return byX.GroupBy(f => f.Y, f => f, (_, byY) => byY.ToList())
.MaxBy(l => l.Count)
.MaxBy(f => f.Z);
}

事情是这样的

项目按 x 分组,因此变量被命名为 byX,这意味着整个 byX 可枚举包含类似的 X

现在您按 Y 对这些分组的项目进行分组。名为 byY 的变量意味着整个 byY 可枚举包含相似的 Y 也有相似的 X

最后,您选择最大的列表,即 winners (MaxyBy(l => l.Count)) 并从获胜者中选择具有最高 Z 的项目> (MaxBy(f => f.Z)).

我使用 byY.ToList() 的原因是为了防止重复枚举,否则会由 Count()MaxBy().


或者,您可以将整个迭代器更改为单个返回语句。

return foos.GroupBy(f => f.X, f => f, (_, byX) => 
byX.GroupBy(f => f.Y, f => f,(__, byY) => byY.ToList())
.MaxBy(l => l.Count)
.MaxBy(f => f.Z));

关于c# - 是否可以将其作为单个高效的 LINQ 查询来执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46920136/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com