用多个长度不同的列表合并相同的项目
本文关键字:列表 项目 合并 | 更新日期: 2023-09-27 18:17:01
我有两个列表
它们长度不同,但类型相同。
我想让List2中的Item替换List1中的Item。
var item1 = new Item { Id = 1, Name = "Test1" };
var item2 = new Item { Id = 2, Name = "Test2" };
var item3 = new Item { Id = 3, Name = "Test3" };
var item4 = new Item { Id = 4, Name = "Test4" };
var item5 = new Item { Id = 5, Name = "Test5" };
var list1 = new List<Item> { item1, item2, item3, item4, item5 };
var list2 = new List<Item> { new Item { Id = 1, Name = "NewValue" } };
因此,我期望一个包含5个项目的列表,其中Id = 1的项目具有值"NewValue"。
如何更好地使用linq.
我延伸我的问题:
如何在不手动复制所有属性的情况下替换被替换的Item ?假设我有100个属性
这是一种方法:
首先定义一个只依赖于Item
类的Id
属性的相等比较器,如下所示:
public class IdBasedItemEqualityComparer : IEqualityComparer<Item>
{
public bool Equals(Item x, Item y)
{
return x.Id == y.Id;
}
public int GetHashCode(Item obj)
{
return obj.Id.GetHashCode();
}
}
然后你可以使用Except
方法获取list1
中没有相应项目的list2
,然后你可以使用Concat
方法将其与list2
连接起来,如下所示:
var result = list1.Except(list2, new IdBasedItemEqualityComparer()).Concat(list2).ToList();
请注意我是如何使用IdBasedItemEqualityComparer
和Except
方法的,因此比较仅基于Id
。
这是我想到的一个解决方案
var list3 = new List<Item>();
foreach (var item in list1)
list3.Add(list2.FirstOrDefault(s => s.Id == item.Id) ?? item);
我认为Linq中的LEFT OUTER JOIN将能够合并两个列表,而不管属性(列)的数量,就像这样:
List<Item> newItems =
(from l1 in list1
join l2 in list2 on l1.Id equals l2.Id into l12
from l2 in l12.DefaultIfEmpty()
select new { Item = (l2 == null) ? l1 : l2 }).Select(r => r.Item).ToList();