Reputation: 351
I have several data in Deal class like the following one:
public class Deal
{
public int Id {get;set;}
public int SiteEdition {get;set;}
public DateTime Date {get;set;}
}
I tried to group them by "Id" and "SiteEdition"; in each group, order by Date, and select top 1 data. My code is like:
List<Deal> dealList = new List<Deal>();
dealList.Add(new Deal(){Id=123, SiteEdition =1, Date = new DateTime(2017,6,1) });
dealList.Add(new Deal(){Id=123, SiteEdition =1 , Date = new DateTime(2017,6,5) });
dealList.Add(new Deal(){Id=123, SiteEdition =2 , Date = new DateTime(2017,6,9) });
dealList.Add(new Deal(){Id=445, SiteEdition =1 , Date = new DateTime(2017,6,14) });
dealList.Add(new Deal(){Id=445, SiteEdition =1 , Date = new DateTime(2017,6,19) });
dealList.Add(new Deal(){Id=445, SiteEdition =2 , Date = new DateTime(2017,6,22) });
dealList.Add(new Deal(){Id=445, SiteEdition =2 , Date = new DateTime(2017,6,25) });
dealList.Add(new Deal(){Id=445, SiteEdition =3 , Date = new DateTime(2017,6,27) });
dealList.Add(new Deal(){Id=445, SiteEdition =3 , Date = new DateTime(2017,6,29) });
List<Deal> finalList = dealList.GroupBy(s=>new{s.Id,s.SiteEdition}).Select(y => new Deal{Id=y.OrderByDescending(m=>m.Date).First().Id, SiteEdition = y.OrderByDescending(m=>m.Date).First().SiteEdition, Date = y.OrderByDescending(m=>m.Date).First().Date}).ToList();
foreach(var item in finalList)
{
Console.WriteLine("Id: " + item.Id + "; SiteEdition: " + item.SiteEdition + " ;DateTime: " + item.Date);
}
It works fine but the linq syntax looks ugly, especially the parts of "y.OrderByDescending(m=>m.Date).First()"....
Is there any way to simplify this syntax?
Upvotes: 1
Views: 61
Reputation: 236218
You don't neet to create new instance of Deal
. Just return one which you already have in the group.
You can use the fact that GroupBy preserves the order of the source sequence within the group - simply sort sequence only once and select first item from each group
dealList.OrderByDescending(d => d.Date)
.GroupBy(d => new { d.Id, d.SiteEdition })
.Select(g => g.First())
.ToList()
Or you can sort each group separately
dealList.GroupBy(d => new { d.Id, d.SiteEdition })
.Select(g => g.OrderByDescending(d => d.Date).First())
.ToList()
Upvotes: 1