我有这门课:
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 技巧吗?
所需的下一个单元格 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)