Ale*_*dro 10 c# linq aggregate-functions
我有一个像下面的循环,我可以使用多个SUM做同样的事情吗?
foreach (var detail in ArticleLedgerEntries.Where(pd => pd.LedgerEntryType == LedgerEntryTypeTypes.Unload &&
pd.InventoryType == InventoryTypes.Finished))
{
weight += detail.GrossWeight;
length += detail.Length;
items += detail.NrDistaff;
}
Run Code Online (Sandbox Code Playgroud)
从技术上讲,你所拥有的可能是做你要求的最有效的方法.但是,您可以在IEnumerable <T>上创建一个名为Each的扩展方法,这可能会使其更简单:
public static class EnumerableExtensions
{
public static void Each<T>(this IEnumerable<T> col, Action<T> itemWorker)
{
foreach (var item in col)
{
itemWorker(item);
}
}
}
Run Code Online (Sandbox Code Playgroud)
并称之为:
// Declare variables in parent scope
double weight;
double length;
int items;
ArticleLedgerEntries
.Where(
pd =>
pd.LedgerEntryType == LedgerEntryTypeTypes.Unload &&
pd.InventoryType == InventoryTypes.Finished
)
.Each(
pd =>
{
// Close around variables defined in parent scope
weight += pd.GrossWeight;
lenght += pd.Length;
items += pd.NrDistaff;
}
);
Run Code Online (Sandbox Code Playgroud)
更新:只需一个额外的说明.上面的例子依赖于一个闭包.变量weight,length和items应该在父作用域中声明,允许它们在每次调用itemWorker操作之后保持不变.为了清楚起见,我已经更新了示例以反映这一点.
您可以调用Sum3次,但是会慢一些,因为它将进行3次循环。
例如:
var list = ArticleLedgerEntries.Where(pd => pd.LedgerEntryType == LedgerEntryTypeTypes.Unload
&& pd.InventoryType == InventoryTypes.Finished))
var totalWeight = list.Sum(pd => pd.GrossWeight);
var totalLength = list.Sum(pd => pd.Length);
var items = list.Sum(pd => pd.NrDistaff);
Run Code Online (Sandbox Code Playgroud)
由于执行延迟,它也会Where每次都重新评估调用,尽管在您的情况下这不是问题。可以通过调用来避免这种情况ToArray,但这将导致数组分配。(它仍然会运行三个循环)
但是,除非您有大量的条目或在紧密的循环中运行此代码,否则您不必担心性能。
编辑:如果您真的想使用LINQ,则可能会滥用Aggregate,如下所示:
int totalWeight, totalLength, items;
list.Aggregate((a, b) => {
weight += detail.GrossWeight;
length += detail.Length;
items += detail.NrDistaff;
return a;
});
Run Code Online (Sandbox Code Playgroud)
这是非常丑陋的代码,但是执行起来几乎和直线循环一样好。
您也可以求和累加器(请参见下面的示例),但这将为列表中的每个项目分配一个临时对象,这是一个愚蠢的主意。(匿名类型是不可变的)
var totals = list.Aggregate(
new { Weight = 0, Length = 0, Items = 0},
(t, pd) => new {
Weight = t.Weight + pd.GrossWeight,
Length = t.Length + pd.Length,
Items = t.Items + pd.NrDistaff
}
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11383 次 |
| 最近记录: |