You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 08:45:03