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

合并List<Result>并按Name/Class去重的实现及代码错误解决

合并Result列表并对Values按Name/Class去重

我现在有两个List<Result>,每个Result包含Key和List<Value>。合并后发现部分Value的Name和Class存在重复,想知道怎么合并这些List<Value>,并且针对每个Key去除Name/Class重复的项?

我的代码示例:

var result1 = new List<Result> { 
    new Result{Key = "X", Values = new List<Value>{new Value{Name = "A1", Class = "C1"}}}, 
    new Result{Key = "Y", Values = new List<Value>{new Value{Name = "B1", Class = "D1"}}} 
};
var result2 = new List<Result> { 
    new Result{Key = "X", Values = new List<Value>{new Value{Name = "A1", Class = "C1"}, new Value{Name = "A2", Class = "C1"}}}, 
    new Result{Key = "Y", Values = new List<Value>{new Value{Name = "B2", Class = "D2"}}} 
};

我尝试的代码(有错误):

var lstResult = new List<Result>();
var groups = result1.Concat(result2).GroupBy(a => a.Key);
foreach (var group in groups) {
 lstResult.Add(new Result { Key = group.Key, Values = group.Select(x => x.Values).ToList() });
}

public class Result { public string Key { get; set; } public List<Value> Values { get; set; } }
public class Value { public string Name { get; set; } public string Class { get; set; } }

遇到的错误:

无法将类型'System.Collections.Generic.List<System.Collections.Generic.List<net452.Program.Value>>'隐式转换为'System.Collections.Generic.List<net452.Program.Value>'


解决方案

你的问题出在group.Select(x => x.Values)这里——这个操作会把每个分组里的Result的Values(也就是List<Value>)都取出来,得到的是一个IEnumerable<List<Value>>,直接ToList()后就是List<List<Value>>,和Result.Values需要的List<Value>类型不匹配。我们需要先展平这个嵌套的列表,再去重。

下面分两种常见场景给你解决方案:

方法一:使用SelectMany展平+自定义去重逻辑(兼容所有.NET版本)

首先,我们需要把分组里所有的Value列表展平成一个IEnumerable<Value>,然后根据Name和Class的组合去重。可以用GroupBy再取每组第一个元素实现去重:

代码实现:

var lstResult = new List<Result>();
var groups = result1.Concat(result2).GroupBy(a => a.Key);

foreach (var group in groups)
{
    // 先展平所有Values列表,再按Name+Class分组去重
    var uniqueValues = group
        .SelectMany(r => r.Values) // 把嵌套的List<Value>展平成单个Value的序列
        .GroupBy(v => new { v.Name, v.Class }) // 按Name和Class的组合分组
        .Select(g => g.First()) // 取每组第一个元素(也就是去重后的结果)
        .ToList();
    
    lstResult.Add(new Result { Key = group.Key, Values = uniqueValues });
}

方法二:使用DistinctBy(.NET Core 3.0+/NET 5+ 推荐)

如果你的项目使用的是.NET Core 3.0及以上版本,或者.NET 5+,可以直接用LINQ的DistinctBy方法,写法更简洁:

代码实现:

var lstResult = result1.Concat(result2)
    .GroupBy(r => r.Key)
    .Select(g => new Result
    {
        Key = g.Key,
        Values = g.SelectMany(r => r.Values)
                  .DistinctBy(v => new { v.Name, v.Class }) // 直接按Name+Class去重
                  .ToList()
    })
    .ToList();

额外优化:给Value类重写Equals和GetHashCode

如果以后经常需要对Value进行去重操作,最好在Value类里重写Equals和GetHashCode方法,这样可以直接使用Distinct()而不需要每次都写分组逻辑:

public class Value 
{ 
    public string Name { get; set; } 
    public string Class { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is Value other)
        {
            return Name == other.Name && Class == other.Class;
        }
        return false;
    }

    public override int GetHashCode()
    {
        // 组合Name和Class的哈希值
        return HashCode.Combine(Name, Class);
    }
}

之后去重就可以直接写:

Values = g.SelectMany(r => r.Values).Distinct().ToList()

内容的提问来源于stack exchange,提问作者user584018

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:48:10