如何合并"列表<Value>"并删除所有键的名称/类对的重复项

  • 本文关键字:合并 何合并 列表 Value 删除 c#
  • 更新时间 :
  • 英文 :


我有两个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(因为值类型的相等比较语义(

最新更新