如何使用 LINQ 对通用列表中的值求和?

B. *_*non 2 c# linq generics

我有这门课:

public class ItemsForMonthYear
{
    public String ItemDescription { get; set; }
    public String monthYr { get; set; }
    public int TotalPackages { get; set; }
    public Decimal TotalPurchases { get; set; }
    public Decimal AveragePrice { get; set; }
    public Double PercentOfTotal { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

...我正在其中存储数据。我有一个用于存储其中 N 个的通用列表:

List<ItemsForMonthYear> itemsForMonthYearList;
Run Code Online (Sandbox Code Playgroud)

...然后我后来从该列表中读取以填充电子表格,这非常简单:

totPackagesCell.Value2 = ifmy.TotalPackages;
totPurchasesCell.Value2 = ifmy.TotalPurchases;
avgPriceCell.Value2 = ifmy.AveragePrice;
Run Code Online (Sandbox Code Playgroud)

...但所需的下一个单元格 val 是基于给定月年的所有 TotalPurchases 值计算得出的值。所以我需要计算所有 ItemsForMonthYear“记录”的“总百分比”值,具有相同的monthYr值。在 SQL 我可以做这样的事情:

SELECT SUM(TotalPurchases) FROM ItemsForMonthYear WHERE monthYr = 'Apr 14'
Run Code Online (Sandbox Code Playgroud)

...然后将该结果除以每个 ItemDescription 的 TotalPurchases 值

IOW,如果“Apr 14”月份的所有 TotalPurchases 总和为 100 万美元,而 ItemDescription“Cocoa Puffs”的 TotalPurchases 为 10 万美元,我可以计算出“Cocoa Puffs”的 PercentOfTotal 为 10% .

我可以“暴力破解”并遍历整个通用列表:

Decimal allTotalPurchases;
foreach (ItemsForMonthYear ifmy in itemsForMonthYearList)
{
    if (ifmy.monthYr.Equals("Apr 14") 
    {
        allTotalPurchases = allTotalPurchases + ifmy.TotalPurchases;
    }
}
Run Code Online (Sandbox Code Playgroud)

...但我认为使用 LINQ 有一种更优雅/性能更友好的方式来实现这一点。我想做这样的事情:

percentOfTotalCell.Value2 = GetPercentForPurchaseForMonthYearAsStr(ifmy.TotalPurchases, curMonth);

private String GetPercentForPurchaseForMonthYearAsStr(decimal totPurchasesForItemMonthYear, string totPurchasesForMonthYear)
{    
    percentOfTotal = // What LINQ magic goes here?
    percentOfTotalStr = percentOfTotal.ToString("P", CultureInfo.InvariantCulture);
    return percentOfTotalStr;
}
Run Code Online (Sandbox Code Playgroud)

...其中参数“ totPurchasesForItemMonthYear ”将是诸如上例中的十万美元之类的值,而参数“ totPurchasesForMonthYear ”将是诸如“Apr 14”之类的值。

有谁知道这个聪明的 LINQ 技巧吗?

Mar*_*ett 5

所需的下一个单元格 val 是基于给定月年的所有 TotalPurchases 值计算得出的值。所以我需要计算所有 ItemsForMonthYear“记录”的“总百分比”值,具有相同的monthYr值。

好吧,首先,您需要获得相同的monthYr

var allMonthYr = itemsForMonthYearList.Where(x => x.monthYr == ifmy.monthYr);
Run Code Online (Sandbox Code Playgroud)

然后是一个简单的Sum

var totalPurchasesOfMonthYr = allMonthYr.Sum(x => x.TotalPurchases);
var percentOfTotal = ifmy.TotalPurchases / totalPurchasesOfMonthYr;
Run Code Online (Sandbox Code Playgroud)

现在,结果证明这是非常低效的——因为你不必要地多次迭代这个列表。更好地分组然后总结一次:

var groupedItemsForMonthYr = itemsForMonthYearList.ToLookup(x => x.monthYr);
var totalsForMonthYr = groupedItemsForMonthYr.ToDictionary(
    x => x.Key, 
    x => x.Sum(x => x.TotalPurchases)
);

var percentOfTotal = ifmy.TotalPurchases / totalsForMonthYr[ifmy.monthYr];
Run Code Online (Sandbox Code Playgroud)