【问题标题】:LINQ Distinct on a particular property and latestLINQ 区分特定属性和最新
【发布时间】:2022-07-11 17:54:37
【问题描述】:

假设我有以下收藏

public class User
{
    public string SSN { get; set; }
    public DateTime StartDate { get; set; }
}

var users = new List<User>
{
    new User {  SSN = "ab", StartDate = new DateTime(2021, 01, 01) },
    new User {  SSN = "ab", StartDate = new DateTime(2021, 01, 02) }, // take this

    new User {  SSN = "ac", StartDate = new DateTime(2021, 01, 01) },
    new User {  SSN = "ac", StartDate = new DateTime(2021, 02, 01) }, // take this

    new User {  SSN = "ad", StartDate = new DateTime(2020, 01, 01) },
    new User {  SSN = "ad", StartDate = new DateTime(2021, 01, 01) },
    new User {  SSN = "ad", StartDate = new DateTime(2022, 01, 01) }, // take this
};

我想要做的是让 SSN 与众不同,但仅在最新的 StartDate 之前,我创建了两个似乎有效的查询。在性能方面有更好的方法吗?

var district = users
    .OrderByDescending(p => p.StartDate)
    .GroupBy(g => g.SSN)
    .Select(x => x.First())
    .ToList();

var ssn = users
    .OrderByDescending(p => p.StartDate)
    .GroupBy(g => g.SSN)
    .Select(x => x.First())
    .Select(x=> x.SSN)
    .ToList();

【问题讨论】:

  • 您要返回带有StartDate 的结果吗?如果不需要返回StartDate,为什么不只是Distinct()这个名字。
  • 出于某种原因,我还需要包含 StartDate

标签: c# linq


【解决方案1】:

为什么要进行两次精确查询(第二次选择 SSN 除外)? 通过第一个查询——产生地区——你已经有了一个用户列表;您需要做的就是使用该结果;像这样:

var ssn = district.Select(x => x.SSN).ToList();

就是这样 - 无需重做。

【讨论】:

  • 第一个查询显示我得到的只是最新的(StartDate)
【解决方案2】:

如果按SSN分组,然后选择相同的SSN,则StartDate的值完全无关。

因此,可以通过选择每个分组的Key来获得不同SSN的列表,如下所示:

var ssns = users.GroupBy(u => u.SSN).Select(g => g.Key);

【讨论】:

  • 这是正确的,但它是请求,可以在未来使用......
【解决方案3】:

既然你提到你需要最新的 StartDate,

SSN 分组并通过.Max() 获取最新的开始日期。

var result = users
    .GroupBy(g => g.SSN)
    .Select(x => new User
    {
        SSN = x.Key,
        StartDate = x.Max(y => y.StartDate)
    })
    .ToList();

Sample .NET Fiddle

【讨论】:

    猜你喜欢
    • 2010-10-04
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多