C# 如何遍历List合并同字段元素?现有实现该如何简化优化?
直接使用LINQ实现(最简方案)
你要找的LINQ核心方法是GroupBy(分组)+ 聚合函数,针对你的需求一行代码即可实现:
var mergedList = list .GroupBy(data => data.type) .Select(group => new Data(group.Key, group.Sum(item => item.amount))) .ToList();
内部逻辑和你自己实现的字典方案一致,语法更简洁,可读性更高。
通用泛型实现(支持任意类型、自定义合并逻辑)
如果需要复用合并逻辑,支持不同类型、自定义分组规则、自定义合并规则,可以封装为泛型扩展方法:
public static class EnumerableExtensions { public static IEnumerable<TResult> MergeDuplicates<TSource, TKey, TValue, TResult>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, // 分组键选择器 Func<TSource, TValue> valueSelector, // 要合并的值选择器 Func<TKey, TValue, TResult> resultBuilder, // 结果构造器 Func<TValue, TValue, TValue> mergeHandler // 自定义合并逻辑 ) { // 参数校验 if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); if (valueSelector == null) throw new ArgumentNullException(nameof(valueSelector)); if (resultBuilder == null) throw new ArgumentNullException(nameof(resultBuilder)); if (mergeHandler == null) throw new ArgumentNullException(nameof(mergeHandler)); Dictionary<TKey, TValue> cache = new Dictionary<TKey, TValue>(); foreach (var item in source) { var key = keySelector(item); var currentValue = valueSelector(item); if (cache.ContainsKey(key)) { cache[key] = mergeHandler(cache[key], currentValue); } else { cache.Add(key, currentValue); } } foreach (var kv in cache) { yield return resultBuilder(kv.Key, kv.Value); } } }
调用示例:
var mergedList = list.MergeDuplicates( d => d.type, // 按type分组 d => d.amount, // 取amount字段合并 (type, sumAmount) => new Data(type, sumAmount), // 构造新的Data对象 (prev, curr) => prev + curr // 合并逻辑为累加 ).ToList();
性能相关说明
你提到的两次遍历问题,第二次遍历的是分组后的字典,时间复杂度为O(k),k是分组后的唯一键数量,远小于原列表长度O(n),性能损耗可以忽略不计。如果确实存在大量无重复数据的场景,且性能要求极高,可以额外增加重复检测逻辑,但绝大多数业务场景下不需要做额外优化,上述两种方案的性能足够。
内容的提问来源于stack exchange,提问作者fafase
相关产品推荐
相关产品推荐

