我正在阅读一个文件并将其中的每一行转换为一个类,我们称之为Record
,然后使用Record
和{{1}返回每个IEnumerable<Record>
}}
因此,每当我对枚举执行操作时,我才开始实际执行这些读取,例如对其执行求和或使用yield return
迭代它。
我确实需要浏览每条记录,然后将其转换为数据库,但由于数据库设计在我的时间之前我需要数据库中每条记录的总计,所以我需要这些总数在我开始将它们翻译成我的数据库之前。
目前,在我开始迭代枚举(例如foreach
或.Count()
)之前,我的枚举上有五个单独的.Sum()
或int i = records.Sum(r => r.SomeField)
操作。这些计数或总和中的每一个将遍历整个文件以分别计算每个。我对这种行为并不满意,并希望找到一种更有效的方法。
如果有任何不同,我使用的是.NET 3.5。
答案 0 :(得分:1)
您可以使用自己的struct
在可通过可枚举对象的单次传递中计算一些值。
public struct ComplexAccumulator
{
public int TotalSumField { get; set; }
public int CountSomethingTrue { get; set; }
}
现在,您可以使用Aggreagate
扩展方法来累积值:
records.Aggregate(default(ComplexAccumulator), (a, r) => new ComplexAccumulator
{
TotalSumFiled = a.TotalSumField + r.SumField,
CountSomethingTrue = a.CountSomethingTrue + r.IsSomethingTrue ? 1 : 0,
});
您可以使用合适的struct
实例代替Tuple
,而不是Tuple<int, int, int>
。类似于add
。
答案 1 :(得分:0)
效率不是LINQ的优势......你需要在这里用手动循环替换一些LINQ东西。
您似乎需要两次通过数据。一个用于汇总:
var sum = 0; //etc.
foreach (var item in items) {
//compute all 5 aggregates here
}
然后一个人翻译数据:
items.Select(item => Translate(item, aggregates))
是否应缓冲items
(例如使用ToList
)取决于可用内存是否可以容纳这些项目。
您可以使用Aggregate
在一次通过中执行所有5个聚合,但这并不比循环更好。它更慢,代码更多,代码可以说是难以理解的。