DarkW1nter
DarkW1nter

Reputation: 2861

use LINQ to remove items from a list based on a date

In C# I have a list locationsList which contains fields location and date, location can appear multiple times with different dates.

If location does appear multiple times I want to only keep the one with the latest date. Is there any way to do this using LINQ rather than iterate through the list and compare the dates of each multiple-occurring location?

Upvotes: 3

Views: 708

Answers (1)

Cyril Gandon
Cyril Gandon

Reputation: 17068

I assume the field location is a string, and you can rebuild your Location object:

class Location {
    public string location { get; set; }
    public DateTime date { get; set; }
}

var distincts = locationsList 
         .GroupBy(location => location.location)
         .Select(grp => new Location {
             location = grp.Key, 
             date = grp.Max(loc => loc.date)
         });

If rebuilding your object is not an option, you can use the MaxBy extension method by MoreLINQ:

var distincts = locationsList 
         .GroupBy(location => location.location)
         .Select(grp => grp.MaxBy(loc => loc.date))

For simplification, here is a non generic version of the MaxBy method, applied to your case:

Location MaxByDate(List<Location> locations){
    Location maxLocation = null;
    var maxDate = DateTime.MinValue;
    foreach(var location in locations) {
        if (location.date > maxDate)
        {
            maxLocation = location;
            maxDate = location.date;
        }
    }
    return maxLocation ;
}

Edit

Another alternative proposed by Flater, slightly worst in performance due to the fact that you must loop twice in each group, one for retrieving the Max, the second loop for finding the match. But very readable and maintainable.

var distincts = locationsList 
     .GroupBy(location => location.location)
     .Select(grp => {
         var maxDate = grp.Max(location => location.date);
         return grp.First(location => location.date == maxDate);
     })

Upvotes: 3

Related Questions