【问题标题】:use LINQ to remove items from a list based on a date使用 LINQ 根据日期从列表中删除项目
【发布时间】:2017-09-14 16:28:10
【问题描述】:

在 C# 中,我有一个列表 locationsList,其中包含字段 locationdatelocation 可以在不同的日期出现多次。

如果location 确实出现多次,我只想保留最新日期的那个。 有没有办法使用 LINQ 来完成此操作,而不是遍历列表并比较每个多次出现位置的日期?

【问题讨论】:

  • 请提供您当前代码的minimal reproducible example
  • 正如 dymanoid 提到的,如果没有代码示例,我们无法真正回答这个问题。根据对您很重要的字段查看数据分组

标签: c# list linq


【解决方案1】:

我假设字段location 是一个字符串,您可以重建您的 Location 对象:

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)
         });

如果重建对象不是一个选项,您可以使用MoreLINQMaxBy 扩展方法:

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

为简化起见,这里是 MaxBy 方法的非通用版本,适用于您的案例:

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 ;
}

编辑

Flater 提出的另一个替代方案,性能稍差,因为您必须在每个组中循环两次,一次用于检索 Max,第二次循环用于查找匹配项。但非常可读和可维护。

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

【讨论】:

  • 没有MoreLINQ也可以做到:Select(group =&gt; group.First(x =&gt; x.Date == group.Max(y =&gt; y.Date))。有点冗长,但可能。 (请注意,我使用First 而不是FirstOrDefault,因为从逻辑上讲,在GroupBy 之后永远不会遇到null)
  • @Flater,它将为原始源中的每个项目在组上计算 Max。这将有可怕的表现。如果您想走那条路线,请在调用 First 之前计算最大值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-17
  • 2015-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多