C#如何以共同id为键将两个Registration列表合并为存储新旧记录的字典
C# 原生不存在三个泛型参数的Dictionary类型,你需要的正确结构是值元组作为Value的字典:Dictionary<int, (List<Registration> OldRecords, List<Registration> NewRecords)>,以下是三种不同场景的实现方案:
方案1:纯LINQ单语句实现(适合中小数据量)
通过给新旧记录打来源标记,再合并分组生成结果,代码简洁易读:
var result = oldReg.Select(r => new { r.id, Source = "Old", Data = r }) .Concat(newReg.Select(r => new { r.id, Source = "New", Data = r })) .GroupBy(x => x.id) .ToDictionary( g => g.Key, g => ( OldRecords: g.Where(x => x.Source == "Old").Select(x => x.Data).ToList(), NewRecords: g.Where(x => x.Source == "New").Select(x => x.Data).ToList() ));
方案2:分组后求并集实现(平衡性能与可读性)
在你原有思路基础上优化,修复了原实现「丢失仅存在旧列表的id」、「字典索引不存在key抛异常」的问题:
// 按id分组生成两个字典,时间复杂度O(n + m) var oldGroup = oldReg.GroupBy(r => r.id).ToDictionary(g => g.Key, g => g.ToList()); var newGroup = newReg.GroupBy(r => r.id).ToDictionary(g => g.Key, g => g.ToList()); // 取所有id的并集生成最终字典 var result = oldGroup.Keys.Union(newGroup.Keys) .ToDictionary( id => id, id => ( OldRecords: oldGroup.TryGetValue(id, out var oldList) ? oldList : new List<Registration>(), NewRecords: newGroup.TryGetValue(id, out var newList) ? newList : new List<Registration>() ));
方案3:性能最优实现(适合超大数据量)
仅需遍历两次列表,无额外分组、求并集开销,性能最高:
var result = new Dictionary<int, (List<Registration> OldRecords, List<Registration> NewRecords)>(); // 写入所有旧记录 foreach (var reg in oldReg) { if (!result.TryGetValue(reg.id, out var pair)) { pair = (new List<Registration>(), new List<Registration>()); } pair.OldRecords.Add(reg); result[reg.id] = pair; } // 写入所有新记录 foreach (var reg in newReg) { if (!result.TryGetValue(reg.id, out var pair)) { pair = (new List<Registration>(), new List<Registration>()); } pair.NewRecords.Add(reg); result[reg.id] = pair; }
内容的提问来源于stack exchange,提问作者I am not Fat
相关产品推荐
相关产品推荐

