Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merging 2 Lists in LINQ

Tags:

vb.net

linq

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)
like image 559
Joss57 Avatar asked Jun 09 '11 14:06

Joss57


1 Answers

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)
like image 146
user7116 Avatar answered Nov 14 '22 20:11

user7116