我尝试按列表分组,然后计算每个组中的项目,然后根据其计数仅选择每个组的最大值。以下代码可以正常工作并完成我的需要。问题是它非常慢,尤其是第二步。您是否知道以更有效的方式实现相同结果的方法?
var grouppedList = sourceList.Where(j => j.field1 == "1000")
.GroupBy(i => new { mask = i.field2.Substring(0, 1), f3 = i.field3, f4 = i.field4 })
.Select(k => new
{
f4 = k.Key.f4,
mask = k.Key.mask,
f3 = k.Key.f3,
Total = k.Count()
});
var totalsList = grouppedList
.Where(i => !grouppedList.Any(j =>
j.mask == i.mask && j.f4 == i.f4 && j.Total > i.Total))
.ToList();
答案 0 :(得分:2)
您的groupedList
不是List
。这是IEnumerable
。所以每次访问它时都会执行它。然后你为它的每一部分访问它(在Where
子句中)。我建议从它创建一个列表(只执行一次查询):
var grouppedList = sourceList.Where(j => j.field1 == "1000")
.GroupBy(i => new { mask = i.field2.Substring(0, 1), f3 = i.field3, f4 = i.field4 })
.Select(k => new
{
f4 = k.Key.f4,
mask = k.Key.mask,
f3 = k.Key.f3,
Total = k.Count()
}).ToList();
另一种可能性是将分组和获取项目与最多Total相结合,我会这样做:
var grouppedList = sourceList.Where(j => j.field1 == "1000")
.GroupBy(i => new { mask = i.field2.Substring(0, 1), f3 = i.field3, f4 = i.field4 })
.Select(k => new
{
f4 = k.Key.f4,
mask = k.Key.mask,
f3 = k.Key.f3,
Total = k.Count()
})
.GroupBy(x => new {x.mask, x.f4})
.Select(x=>x.OrderBydescending(t=>t.Total).First());
.ToList();
答案 1 :(得分:1)
这段代码看起来很慢的原因可能就是你要两次迭代grouppedList
。
var totalsList = grouppedList.Where(i => !grouppedList.Any(
j => j.mask == i.mask && j.f4 == i.f4 && j.Total > i.Total)
).ToList();
将对groppedList
中所有元素的内部Where
- 语句中的groppuedList
进行迭代。您可以考虑使用ToList
强制立即执行例如:
var grouppedList = sourceList.Where(j => j.field1 == "1000")
.GroupBy(i => new { mask = i.field2.Substring(0, 1), f3 = i.field3, f4 = i.field4 })
.Select(k => new
{
f4 = k.Key.f4,
mask = k.Key.mask,
f3 = k.Key.f3,
Total = k.Count()
}).Tolist(); // this forces an immediate execution of your select-statement
现在打电话给你的第二个陈述
var totalsList = grouppedList.Where(i => !grouppedList.Any(j => j.mask == i.mask && j.f4 == i.f4 && j.Total > i.Total)).ToList();
它将使用allready物化列表,而不是一次又一次地执行查询。