Reputation: 21206
I have 2 lists.
They are different in length but same type.
I want that an Item from List2 replaces an equal item in List1.
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" } };
As a result I expect a list with 5 items where the item with Id = 1 has a value "NewValue".
How can I do that preferable with linq.
UPDATE
I extend my question:
How can the replacement of the replaced Item happen without copying all properties manually. Just imagine I have 100 properties...
Upvotes: 3
Views: 114
Reputation: 1421
I think LEFT OUTER JOIN in Linq will be able to merge 2 lists regardless of number of properties(columns) like this:
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();
Upvotes: 1
Reputation: 3845
Off the top of my head this is one solution
var list3 = new List<Item>();
foreach (var item in list1)
list3.Add(list2.FirstOrDefault(s => s.Id == item.Id) ?? item);
Upvotes: 1
Reputation: 27861
This is one way to do it:
First define an equality comparer that depends only on the Id
property of the Item
class like this:
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();
}
}
Then you can take items list1
that don't have corresponding items in list2
using the Except
method and then you can concatenate that with list2
using the Concat
method like this:
var result = list1.Except(list2, new IdBasedItemEqualityComparer()).Concat(list2).ToList();
Notice how I use the IdBasedItemEqualityComparer
with the Except
method, so that comparison is based only on Id
.
Upvotes: 3