我有两个Result
列表和一个Value
列表,如果我们合并两个结果列表,则会有一些重复的Name/class。
如何合并List<Value>
并删除所有密钥的名称/类对的重复项?
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; }
}
在上面的代码中,我在第行收到错误,
Values = group.Select(x => x.Values).ToList() //error
无法隐式转换类型"System.Collections.Generic.List<System.Collections.Generic.List<net452.Program.Value>gt;'到'System.Collections.Generic.List<net452.Program.Value>'
以下内容有效且没有重复。它基本上与АндрейСаяпин的答案相同,但GetHashCode
也被覆盖。
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; }
public override bool Equals(object other)
=> other is Value o && Name == o.Name && Class == o.Class;
public override int GetHashCode() => (Name, Class).GetHashCode();
}
class Program
{
static void Main(string[] args)
{
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.SelectMany(x => x.Values).Distinct().ToList()
});
}
}
}
我不知道如何使用linq来实现这一点。但是你可以试试这个功能。
List<Result> MergeList(List<Result>list1, List<Result>list2) {
var myList = list1;
foreach (var item in list2)
{
var obj = myList.Where(x => x.Key == item.Key).FirstOrDefault(); ;
if (obj != null)
{
foreach (var vals in item.Values)
{
if (!obj.Values.Any(x => x.Class == vals.Class && x.Name == vals.Name))
{
obj.Values.Add(vals);
}
}
}
else
{
myList.Add(item);
}
}
return myList;
}
如果为Value
类指定Equals
,则可以按照现在的方式执行,添加以下内容:
Values = group.SelectMany(x => x.Values).Distinct().ToList()
如果Value
类是不可变的,那么这样做是安全的,并且看起来像
class Value {
public override bool Equals(object other) => other is Value v && v.Name == Name && v.Class == Class;
}
如文档中所述,默认的相等比较器用于确定项目是否与不同
顺便说一句,你可以让Value
成为一个结构,并免费获得正常工作的Distinct
(因为值类型的相等比较语义(