7

I have an class which contains the following properties:

public class SomeClass()
{
public Int32 ObjectId1 {get;set;}
public Int32 ObjectId2 {get;set;}
public Int32 ActiveThickeness {get;set;}
public Int32 ActiveFilterThickness {get;set;}
}

I also have 2 lists:

List<SomeClass> A
List<SomeClass> B

List A has data:

| ObjectId1 | ObjectId2 | ActiveThickness | ActiveFilterThickness |
-------------------------------------------------------------------
|     1     |     3     |       50        |           0           |
 ------------------------------------------------------------------
|     1     |     2     |       400       |           0           |
-------------------------------------------------------------------
|     4     |    603    |       27        |           0           |
-------------------------------------------------------------------

List B has data:

| ObjectId1 | ObjectId2 | ActiveThickness | ActiveFilterThickness |
-------------------------------------------------------------------
|     1     |     3     |       0         |         13671         |
 ------------------------------------------------------------------
|     1     |     2     |       0         |          572          |
-------------------------------------------------------------------
|    29     |    11     |       0         |         4283          |
-------------------------------------------------------------------

I want to merge A and B (using LINQ if possible) into List C of SomeCalss which contains data as followed:

| ObjectId1 | ObjectId2 | ActiveThickness | ActiveFilterThickness |
-------------------------------------------------------------------
|     1     |     3     |       50        |         13671         |
 ------------------------------------------------------------------
|     1     |     2     |       400       |          572          |
-------------------------------------------------------------------
|    29     |    11     |       0         |         4283          |
-------------------------------------------------------------------
|     4     |    603    |       27        |           0           |
-------------------------------------------------------------------

How can I achieve that?

Cœur
  • 32,421
  • 21
  • 173
  • 232
Shpongle
  • 217
  • 7
  • 15

2 Answers2

11

Use GroupBy to group common objects and Sum to sum required properties

        var ab = A.Concat(B).GroupBy(x => new
                                              {
                                                      x.ObjectId1,
                                                      x.ObjectId2
                                              });


        var result = ab.Select(x => new SomeClass
                                        {
                                                ObjectId1 = x.Key.ObjectId1,
                                                ObjectId2 = x.Key.ObjectId2,
                                                ActiveFilterThickness = x.Sum(i => i.ActiveFilterThickness),
                                                ActiveThickeness = x.Sum(i => i.ActiveThickeness)
                                        });
Evgeny Lukashevich
  • 1,393
  • 12
  • 25
1

See LINQ - Full Outer Join (SO).

By doing a left outer join and a right outer join, and then taking the union of those two, you should get what you're looking for.

var leftOuterJoin = from someclass1 in A
                    join someclass2 in B
                    on someclass1.ObjectID2 equals someclass2.ObjectID2
                    into temp
                    from item in temp.DefaultIfEmpty(new SomeClass(){ objectID1 = someclass1.objectID1, ... })
                    select new SomeClass()
                    {
                        ...
                    };
var rightOuterJoin = from someclass2 in B
                     join someclass1 in A
                     on someclass1.ObjectID2 equals someclass2.ObjectID2
                    into temp
                    from item in temp.DefaultIfEmpty(new SomeClass(){ objectID1 = someclass1.objectID1, ... })
                    select new SomeClass()
                    {
                        ...
                    };
var fullOuterJoin = leftOuterJoin.Union(rightOuterJoin);
Community
  • 1
  • 1
Destrictor
  • 752
  • 1
  • 4
  • 15
  • One of the problems with Linq is it's lack of an elegant way to do left, right, and full outter joins. – juharr Dec 16 '12 at 12:51
  • @juharr True, but in the link I provided, someone made an extension to do full outer joins. You should look into it. – Destrictor Dec 16 '12 at 13:32