用多个长度不同的列表合并相同的项目

本文关键字:列表 项目 合并 | 更新日期: 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();

请注意我是如何使用IdBasedItemEqualityComparerExcept方法的,因此比较仅基于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();