C# 如何使用LINQ按条件求和后新增汇总行到现有列表
问题描述
我有如下数据列表:
var data = new List<SummaryTabData>() { new SummaryTabData(){ LP = "LP_1", assetClass = "Asset_CFD_Long", avgSlippagePts = 54.23} , new SummaryTabData(){ LP = "LP_1", assetClass = "Asset_FX_Long", avgSlippagePts = 61.41} , new SummaryTabData(){ LP = "LP_1", assetClass = "Asset_FX_Short", avgSlippagePts = 11.48} , new SummaryTabData(){ LP = "LP_1", assetClass = "Asset_CFD_Short", avgSlippagePts = 63.51} , new SummaryTabData(){ LP = "LP_2", assetClass = "Asset_FX_Long", avgSlippagePts = 6.51} , new SummaryTabData(){ LP = "LP_2", assetClass = "Asset_FX_Short", avgSlippagePts = 13.51} };
我的需求是:为每个LP对应的每对Asset_CFD_Long/Asset_CFD_Short和Asset_FX_Long/Asset_FX_Short分别新增一条汇总行。如示例所示,现有数据可能包含2种或4种资产类别,且数据未经过排序。
最终预期结果如下:
var data = new List<SummaryTabData>() { new SummaryTabData(){ LP = "LP_1", assetClass = "Asset_CFD_Long", avgSlippagePts = 54.23} , new SummaryTabData(){ LP = "LP_1", assetClass = "Asset_CFD_Short", avgSlippagePts = 63.51} , // 为LP_1的CFD资产新增的汇总行 new SummaryTabData(){ LP = "LP_1", assetClass = "CFD_Total", avgSlippagePts = 117.74} , new SummaryTabData(){ LP = "LP_1", assetClass = "Asset_FX_Long", avgSlippagePts = 61.41} , new SummaryTabData(){ LP = "LP_1", assetClass = "Asset_FX_Short", avgSlippagePts = 11.48} , // 为LP_1的FX资产新增的汇总行 new SummaryTabData(){ LP = "LP_1", assetClass = "FX_Total", avgSlippagePts = 72.89} , new SummaryTabData(){ LP = "LP_2", assetClass = "Asset_FX_Long", avgSlippagePts = 6.51} , new SummaryTabData(){ LP = "LP_2", assetClass = "Asset_FX_Short", avgSlippagePts = 13.51}, // 为LP_2的FX资产新增的汇总行 new SummaryTabData(){ LP = "LP_2", assetClass = "FX_Total", avgSlippagePts = 20.02}, };
请问该需求可以通过LINQ查询实现,还是需要使用传统for循环方案实现?
回答
两种方案都可以实现,你完全可以直接用LINQ完成该需求,不需要额外编写复杂的for循环逻辑。
实现思路是先按LP分组,每个LP分组内再提取资产大类(CFD/FX)做二次分组,每个资产分组内先返回排序后的明细记录,再追加计算好的汇总行,最后把所有分组的结果扁平化合并成新的列表即可。
参考实现代码如下:
var result = data // 第一层按LP分组 .GroupBy(x => x.LP) .SelectMany(lpGroup => // 每个LP下按资产大类(CFD/FX)二次分组 lpGroup.GroupBy(x => x.assetClass.Split('_')[1]) .OrderBy(g => g.Key) // 保证CFD在前FX在后,和示例输出顺序一致 .SelectMany(assetGroup => // 先返回当前资产大类下的明细(按Long、Short排序),再追加汇总行 assetGroup.OrderBy(x => x.assetClass) .Append(new SummaryTabData { LP = lpGroup.Key, assetClass = $"{assetGroup.Key}_Total", avgSlippagePts = assetGroup.Sum(x => x.avgSlippagePts) }) ) ).ToList();
上述代码会自动处理仅存在FX、或者同时存在CFD+FX的LP的汇总逻辑,也不需要你提前对原始数据做排序处理,输出结果和你给出的预期完全一致。如果你更习惯命令式写法,用传统for循环遍历统计也可以实现,只是LINQ的写法更简洁,也更贴合这类聚合统计的场景。
内容的提问来源于stack exchange,提问作者pewocis495
相关产品推荐
相关产品推荐

