Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get an item from a IGrouping based on the highest date

Tags:

c#

lambda

linq

In a IEnumerable<Appointment> that contains appointments defined as:

class Appointment
{
  public string Name { get; set; }
  public DateTime LastModified { get; set; }
  public bool IsCancelled { get; set; }
}

which in practice can be like:

"Jon S" | 25-02-2011 16:14:40 | true
"Jon S" | 25-04-2011 22:15:44 | false
"Marc G" | 15-11-2011 16:09:00 | true
"Marc G" | 21-12-2011 16:11:00 | false
"Marc G" | 20-12-2011 16:24:00 | true
"Eric L" | 13-06-2011 19:10:00 | false
"Reed C" | 13-04-2011 09:10:00 | true
"Reed C" | 13-06-2011 19:10:00 | false
"John G" | 04-01-2011 06:12:00 | true
"Jon S" | 25-03-2011 12:24:42 | true

This collection has to be downsized to a collection that contains only the appointments with the highest date LastModified of each distinct Name.

"Jon S" | 25-04-2011 22:15:44 | false
"Marc G" | 21-12-2011 16:11:00 | false
"Eric L" | 13-06-2011 19:10:00 | false
"Reed C" | 13-06-2011 19:10:00 | false
"John G" | 04-01-2011 06:12:00 | true

I am a bit confused how to do this. When I tried:

 .GroupBy(n => n.Name)
 .Select(d => d.Max(t => t.LastModified));

It seems to deliver the correct dates, but the whole entity is needed, what am I missing?.

UPDATE/note: This is a large collection with about 10.000 unsorted items, delivered by a service I cannot modify. Each distinct group has about 20 elements.

like image 853
Caspar Kleijne Avatar asked Jun 30 '11 20:06

Caspar Kleijne


3 Answers

.GroupBy(n => n.Name)
.Select(d => d.OrderByDescending(t => t.LastModified).First())
like image 109
BFree Avatar answered Nov 20 '22 16:11

BFree


.GroupBy(appt => appt.Name, (key, group) =>
{
    var maxDt = group.Max(appt => appt.LastModified);
    return group.First(appt => appt.LastModified == maxDt);
});

Possibly better performance than previous solution

like image 1
a553 Avatar answered Nov 20 '22 16:11

a553


In Linq query syntax:

        var last = from app in apps
                   orderby app.LastModified descending
                   group app by app.Name into grp
                   select grp.First();                    

Your version with max:

        var lastApp = from app in apps
                      group app by app.Name into grp
                      select grp.First(last => last.LastModified == grp.Max( g => g.LastModified));  
like image 1
Marino Šimić Avatar answered Nov 20 '22 17:11

Marino Šimić