如何基于两个参数正确使用.GroupBy实现数据拆分?
问题:按供应商和零件类型拆分数据集
我有一组需要按两个字段拆分的数据,尝试使用.GroupBy但未得到预期结果。拆分条件如下:
- 按
supplierName拆分; - 若第一步得到的记录集中存在相同
partTypeCode的记录,需将其拆分为单独集合。
示例数据中有3条autozone的记录和1条orielly的记录,期望得到指定的拆分结果。
我的尝试方法:
- 以下代码仅实现第一步,且会将OIL_FILTER的记录分组,不符合需求:
var groupedList = items.GroupBy(x => x.supplierName) .Select(g => new { Key = g.Key, Count = g.Count(), itemGroup = g.GroupBy(x => x.partTypeCode) }).ToList();
- 以下代码会将相同partTypeCode的记录合并,也不符合需求:
var groupedList = items.GroupBy(x => new { x.supplierName, x.partTypeCode }).ToList();
我的问题:
.GroupBy是否是实现我需求的正确方式?- 若不是,实现该需求的理想方法是什么?
数据:
[ { "cartItemId": "7de1881e-41b3-493f-a342-c8e7c7d6c6ff", "partTypeCode": "OIL_FILTER", "quantity": 1, "manufacturerCode": "CHL", "supplierName": "autozone" }, { "cartItemId": "111881e-41b3-493f-a342-c8e7c7d6c6ff", "partTypeCode": "VEHICLE_BATTERY", "quantity": 1, "manufacturerCode": "CHL", "supplierName": "autozone" }, { "cartItemId": "222881e-41b3-493f-a342-c8e7c7d6c6ff", "partTypeCode": "F_DS_WIPER_BLADE", "quantity": 1, "manufacturerCode": "CHL", "supplierName": "orielly" }, { "cartItemId": "3331881e-41b3-493f-a342-c8e7c7d6c6ff", "partTypeCode": "OIL_FILTER", "quantity": 1, "manufacturerCode": "CHL", "supplierName": "autozone" } ]
期望输出:
1st collection [ { "cartItemId": "7de1881e-41b3-493f-a342-c8e7c7d6c6ff", "partTypeCode": "OIL_FILTER", "quantity": 1, "manufacturerCode": "CHL", "supplierName": "autozone" }, { "cartItemId": "111881e-41b3-493f-a342-c8e7c7d6c6ff", "partTypeCode": "VEHICLE_BATTERY", "quantity": 1, "manufacturerCode": "CHL", "supplierName": "autozone" } ] 2nd collection [ { "cartItemId": "222881e-41b3-493f-a342-c8e7c7d6c6ff", "partTypeCode": "F_DS_WIPER_BLADE", "quantity": 1, "manufacturerCode": "CHL", "supplierName": "orielly" } ] 3rd collection [ { "cartItemId": "3331881e-41b3-493f-a342-c8e7c7d6c6ff", "partTypeCode": "OIL_FILTER", "quantity": 1, "manufacturerCode": "CHL", "supplierName": "autozone" } ]
回答
.GroupBy是否适用?
.GroupBy可以作为实现的基础,但单纯的嵌套分组或复合键分组无法直接满足需求——因为你需要的不是合并相同partTypeCode的记录,而是在同一供应商组内,保留唯一partTypeCode的记录在一个集合,重复的partTypeCode记录单独成集合。
实现方法
通过遍历+跟踪的方式可以实现需求,具体步骤:
- 按
supplierName分组,获取每个供应商的记录列表; - 对每个供应商的记录,跟踪当前批次已包含的
partTypeCode; - 遍历记录:若当前零件类型已在批次中,则将当前批次存入结果,新建批次并加入当前记录;否则直接加入当前批次;
- 遍历结束后,将最后一个批次存入结果。
对应的C#代码:
// 替换YourItemType为你的实体类型 var result = new List<List<YourItemType>>(); foreach (var supplierGroup in items.GroupBy(x => x.supplierName)) { var partTypeTracker = new HashSet<string>(); List<YourItemType> currentBatch = new List<YourItemType>(); foreach (var item in supplierGroup) { if (partTypeTracker.Contains(item.partTypeCode)) { if (currentBatch.Any()) { result.Add(currentBatch); currentBatch = new List<YourItemType>(); partTypeTracker.Clear(); } } currentBatch.Add(item); partTypeTracker.Add(item.partTypeCode); } if (currentBatch.Any()) { result.Add(currentBatch); } }
代码说明
- 外层
GroupBy确保同一供应商的记录被统一处理; HashSet<string>用于高效跟踪当前批次的零件类型,避免重复;- 当遇到重复零件类型时,立即拆分批次,保证每个批次内无重复零件类型;
- 最后不要遗漏未存入的最后一个批次。
这段代码会生成你期望的三个集合,完全匹配需求。
内容的提问来源于stack exchange,提问作者GThree
相关产品推荐
相关产品推荐

