You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用LINQ从ListA筛选含最新StartDate的对象生成ListB?

使用LINQ筛选每组最新StartDate的对象

嘿,这个需求我之前处理过,用LINQ实现其实挺清晰的,但有个关键细节得注意——你的StartDate是字符串类型,直接比字符串会出问题(比如"02.01.2000"字符串比"01.12.2001"大,但实际日期更早),所以得先转成DateTime再比较。

先明确下你的场景:

示例数据

  • ListA原始内容:

    OA 001 01.01.2000
    OA 001 02.01.2000
    OA 001 01.12.2001
    OB 002 01.01.2000

  • ListB期望结果:

    OA 001 01.12.2001
    OB 002 01.01.2000

简单来说,就是按Code+Ref分组,每组只留StartDate最新的那个对象。下面给你两种高效的实现方式:

方法一:分组后排序取首项(可读性优先)

这种方法逻辑直白,新手也能一眼看懂,先分组再排序取最新:

// 先定义你的对象类,假设叫MyItem
public class MyItem
{
    public string Code { get; set; }
    public string Ref { get; set; }
    public string StartDate { get; set; }
}

// 核心LINQ代码
var ListB = ListA
    // 按Code和Ref组合分组,确保同组是同一类条目
    .GroupBy(item => new { item.Code, item.Ref })
    .Select(group => 
        // 每组按StartDate转成DateTime后降序排列,第一个就是最新的
        group.OrderByDescending(item => DateTime.ParseExact(item.StartDate, "dd.MM.yyyy", null))
             .First())
    .ToList();

⚠️ 小提示:用ParseExact比Parse更安全,因为它指定了固定格式dd.MM.yyyy,避免系统文化差异导致解析错误(比如有些地区是MM.dd.yyyy)。

方法二:用MaxBy提升性能(大数据量优先)

如果你的ListA数据量很大,排序的开销会比较高(排序是O(n log n)),这时候用MaxBy会更高效(O(n)时间复杂度)。如果你能引入MoreLINQ库,直接用就行:

// 先安装MoreLINQ的NuGet包
var ListB = ListA
    .GroupBy(item => new { item.Code, item.Ref })
    .Select(group => group.MaxBy(item => DateTime.ParseExact(item.StartDate, "dd.MM.yyyy", null)))
    .ToList();

要是不想加第三方库,也可以自己写个简单的MaxBy扩展方法,不过大多数场景下第一种方法已经够用了。

额外避坑指南

  • 处理无效日期:如果ListA里有格式不对的日期字符串,ParseExact会抛异常,建议先过滤掉无效条目:
var ListB = ListA
    // 先筛选出能正确解析的日期条目
    .Where(item => DateTime.TryParseExact(item.StartDate, "dd.MM.yyyy", null, System.Globalization.DateTimeStyles.None, out _))
    .GroupBy(item => new { item.Code, item.Ref })
    .Select(group => 
        group.OrderByDescending(item => DateTime.ParseExact(item.StartDate, "dd.MM.yyyy", null))
             .First())
    .ToList();
  • 重复最新日期:如果同一组里有多个对象的StartDate都是最新的,上面的方法只会取第一个。要是需要保留所有最新的,把First()换成Where(item => DateTime.ParseExact(item.StartDate, "dd.MM.yyyy", null) == group.Max(x => DateTime.ParseExact(x.StartDate, "dd.MM.yyyy", null)))就行。

内容的提问来源于stack exchange,提问作者Flat_Cap_Hat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:03:57