C#按多字段分组并将空值视为部分匹配实现方案咨询
实现带空值匹配的多字段分组(C#)
需求分析
需要将列表中的项按Amount、Type、Code三个字段分组,规则是:只要项的非null字段与某组的对应非null字段完全匹配,就将该项归入该组(项的null字段不影响匹配)。
实现思路
核心逻辑是动态维护每个分组的“特征标识”:
- 遍历每个项,查找是否存在已有的分组,使得项的每个字段要么与分组特征的对应字段相等,要么为null;
- 找到匹配分组后,更新分组的特征(将分组中为null的字段替换为当前项的非null值);
- 找不到匹配分组时,新建一个以当前项字段为特征的分组。
代码实现
首先定义数据模型:
public class Item { public int? Amount { get; set; } public string Type { get; set; } public string Code { get; set; } }
然后实现分组逻辑:
// 示例数据 var items = new List<Item> { new Item { Amount = 50, Type = "Test", Code = "AA" }, new Item { Amount = 50, Type = "Test2", Code = "BB" }, new Item { Amount = null, Type = "Test", Code = "AA" }, new Item { Amount = 45, Type = "Test3", Code = "CC" }, new Item { Amount = 50, Type = "Test", Code = null }, new Item { Amount = 50, Type = "Test", Code = "AB" } }; // 存储分组:每组包含特征标识和对应的项列表 var groups = new List<(int? GroupAmount, string GroupType, string GroupCode, List<Item> Items)>(); foreach (var item in items) { // 查找匹配的分组 var matchedGroup = groups.FirstOrDefault(g => (g.GroupAmount == null || item.Amount == null || g.GroupAmount == item.Amount) && (g.GroupType == null || item.Type == null || g.GroupType == item.Type) && (g.GroupCode == null || item.Code == null || g.GroupCode == item.Code)); if (matchedGroup != default) { // 更新分组的特征:用当前项的非null值填补分组特征中的null var updatedAmount = matchedGroup.GroupAmount ?? item.Amount; var updatedType = matchedGroup.GroupType ?? item.Type; var updatedCode = matchedGroup.GroupCode ?? item.Code; // 移除旧分组,添加更新后的分组 groups.Remove(matchedGroup); matchedGroup.Items.Add(item); groups.Add((updatedAmount, updatedType, updatedCode, matchedGroup.Items)); } else { // 新建分组 groups.Add((item.Amount, item.Type, item.Code, new List<Item> { item })); } } // 输出分组结果 foreach (var (amount, type, code, itemsInGroup) in groups) { var amountDisplay = amount.HasValue ? amount.ToString() : "null"; var typeDisplay = type ?? "null"; var codeDisplay = code ?? "null"; Console.WriteLine($"分组: {amountDisplay}/null + {typeDisplay} + {codeDisplay}/null"); foreach (var item in itemsInGroup) { Console.WriteLine($" - Amount: {item.Amount}, Type: {item.Type}, Code: {item.Code}"); } }
代码说明
- 分组特征的动态更新:当有新项加入分组时,分组的null字段会被新项的非null值覆盖,确保后续项能正确匹配;
- 匹配逻辑:通过
FirstOrDefault查找满足条件的分组,三个字段分别进行“相等或其中一个为null”的判断; - 输出结果:按照示例格式展示分组特征和组内的所有项。
运行上述代码后,会得到你需要的4个分组,与示例完全一致。
内容的提问来源于stack exchange,提问作者wingthor
相关产品推荐
相关产品推荐

