如何通过公共属性合并两个不同类型的C#对象列表
实现方案
核心思路
取两个列表所有去重的CustomerId,遍历每个id分别匹配两个列表的对应数据,组装为目标类型对象,实现类似SQL全外连接的效果,覆盖仅在单个列表中出现的CustomerId场景。
代码实现
基础版本(适合小数据量)
逻辑简单直接,无需额外预处理,适合数据量低于千级的场景:
// 输入的两个原始列表,替换为你自己的获取逻辑 List<CustomerMRMetric> mrList = GetCustomerMRMetrics(); List<CustomerLRMetric> lrList = GetCustomerLRMetrics(); // 提取所有去重的CustomerId var allCustomerIds = mrList.Select(m => m.CustomerId) .Union(lrList.Select(l => l.CustomerId)) .ToList(); // 组装合并后的列表 List<CustomerMetrics> mergedList = allCustomerIds.Select(id => new CustomerMetrics { CustomerId = id, MRMetrics = mrList.FirstOrDefault(m => m.CustomerId == id)?.MRMetrics, LRMetrics = lrList.FirstOrDefault(l => l.CustomerId == id)?.LRMetrics }).ToList();
高性能版本(适合大数据量)
先将两个列表转为以CustomerId为键的字典,查找复杂度降为O(1),整体时间复杂度为O(n+m),适合万级及以上数据量的场景:
// 输入的两个原始列表,替换为你自己的获取逻辑 List<CustomerMRMetric> mrList = GetCustomerMRMetrics(); List<CustomerLRMetric> lrList = GetCustomerLRMetrics(); // 预处理为字典提升查找效率 var mrDict = mrList.ToDictionary(m => m.CustomerId, m => m.MRMetrics); var lrDict = lrList.ToDictionary(l => l.CustomerId, l => l.LRMetrics); // 提取所有去重的CustomerId var allCustomerIds = mrDict.Keys.Union(lrDict.Keys).ToList(); // 组装合并后的列表 List<CustomerMetrics> mergedList = allCustomerIds.Select(id => new CustomerMetrics { CustomerId = id, MRMetrics = mrDict.TryGetValue(id, out var mr) ? mr : null, LRMetrics = lrDict.TryGetValue(id, out var lr) ? lr : null }).ToList();
可选优化
如果你不希望MRMetrics/LRMetrics为null,避免后续使用时出现空引用异常,可将匹配不到时的返回值改为空字典:
MRMetrics = mrDict.TryGetValue(id, out var mr) ? mr : new Dictionary<int, decimal>(), LRMetrics = lrDict.TryGetValue(id, out var lr) ? lr : new Dictionary<int, string>()
内容的提问来源于stack exchange,提问作者user1890098
相关产品推荐
相关产品推荐

