I have two Lists of custom objects:
List1: Year, Month, ValueA
List2: Year, Month, ValueB
I want to get a third List with a merge between the two:
List3: Year, Month, ValueA, ValueB
Is there any elegant way to perform that in LINQ VB.Net?
Example:
List1:
2010 - 6 - 2
2010 - 7 - 5
2010 - 10 - 3
List2:
2010 - 7 - 2
2010 - 8 - 1
2010 - 10 - 2
List3 (result):
2010 - 6 - 2 - 0
2010 - 7 - 5 - 2
2010 - 8 - 0 - 1
2010 - 10 - 3 - 2
Thanks in advance.
Solution VB.Net translation of the solution :
Dim ListA = From a In List1
Group Join b In List2
On a.Year Equals b.Year And a.Month Equals b.Month Into bGroup = Group
From b In bGroup.DefaultIfEmpty()
Select a.Year, a.Month, a.Value1, Value2 = If(b Is Nothing, 0, b.Value2)
Dim ListB = From b In List2
Group Join a In List1
On b.Year Equals a.Year And b.Month Equals a.Month Into aGroup = Group
From a In aGroup.DefaultIfEmpty()
Select b.Year, b.Month, Value1 = If(a Is Nothing, 0, a.Value1), b.Value2
Dim List3 = ListA.Union(ListB)
Sure, you're looking to perform a Full Outer Join on the data, which doesn't exist in LINQ, so we fake it with two unioned Left Outer Joins:
var A = from a in List1
join b in List2 on new { a.Year, a.Month } equals new { b.Year, b.Month }
into bgroup
from b in bgroup.DefaultIfEmpty()
select new { a.Year, a.Month, a.ValueA, ValueB = (b == null ? 0 : b.ValueB) };
var B = from b in List2
join a in List1 on new { b.Year, b.Month } equals new { a.Year, a.Month }
into agroup
from a in agroup.DefaultIfEmpty()
select new { b.Year, b.Month, ValueA = (a == null ? 0 : a.ValueA), b.ValueB };
var List3 = A.Union(B);
Many apologies for the C#, I could not get my VB.Net example to work for the life of me. You need two left outer joins to be unioned to produce the correct answer. None of the code converters I tried worked either.
The following is VB.Net that LINQPad chokes on, but every example I can find says should be correct:
Dim A = From a In List1 _
Group Join b In List2 _
On New With { a.Year, a.Month } Equals New With { b.Year, b.Month} _
Into bGroup = Group _
From b In bGroup.DefaultIfEmpty() _
Select a.Year, a.Month, a.ValueA, ValueB = If(b Is Nothing, 0, b.ValueB)
Dim B = From b In List2 _
Group Join a In List1 _
On New With { b.Year, b.Month } Equals New With { a.Year, a.Month} _
Into aGroup = Group _
From a In aGroup.DefaultIfEmpty() _
Select b.Year, b.Month, ValueA = If(a Is Nothing, 0, a.ValueA), b.ValueB
Dim List3 = A.Union(B)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With