tags:

views:

199

answers:

3

I have two lists of objects, using Linq I would like to merge them, but where the two lists contain objects with the same key, I only want the one with the greatest LastUpdated Value.

I thought that I could somehow get a list grouping by key a with max(LastUpdated) then join back to the list joining on key and LastUpdated, but there must be a more efficient way...

List<MyObject> lstListA = new List<MyObject>;
List<MyObject> lstListB = new List<MyObject>;

public class MyObject
{
    public string Key {get;set;}
    public string Value {get;set;}
    public DateTime LastUpdated {get;set;}
}
+13  A: 

One option, using DistinctBy from MoreLINQ:

var query = lstListA.Concat(lstListB)
                    .OrderByDescending(x => x.LastUpdated)
                    .DistinctBy(x => x.Key);
Jon Skeet
How does the DistinctBy differ from using Distinct with a comparer? Will the result be the same?
Jeremy
@Jeremy: Yes, the result is the same - DistinctBy is just easier :)
Jon Skeet
A: 

A bit comvoluted, but this seems to work as well:

var mergedItems = lstListA.Concat(lstListB);

mergedItems =
    (from item in mergedItems
    group item by item.Key into grp
    let sameKey = mergedItems.Where(obj => obj.Key == grp.Key)
    select sameKey.Where(obj => obj.LastUpdated == grp.Max(obj2 => obj2.LastUpdated)).Single()
).ToList();
Konamiman
A: 

Classic pick-a-winner.

IEnumerable<MyObject> query = lstListA
  .Concat(lstListB)
  .GroupBy(x => x.Key)
//now work with each group to pick a winner
  .Select(g => g.OrderByDescending(x => x.LastUpdated).First())
David B