LINQ问题我想获取每个寄存器的表的最后记录

bzzcjhmw  于 2022-12-06  发布在  其他
关注(0)|答案(3)|浏览(129)

我有这样的清单:

var raw = new[] {    new { Title = "Sergio", Date= "18-12-2021"},
                     new { Title = "Sergio", Date= "18-10-2021"},
                     new { Title = "Sergio", Date= "18-11-2021"},
                     new { Title = "Jose", Date= "19-12-2021"},
                     new { Title = "Jose", Date= "18-12-2021"},
                     new { Title = "Jose", Date= "17-12-2021"},
                     new { Title = "Marco", Date= "16-12-2021"}
        };

我想要一个包含每个“标题”的最后注册日期的列表。例如,这将是输出:

raw = {{ Title = "Sergio", Date= "18-12-2021"},
{ Title = "Jose", Date= "19-12-2021"},
{ Title = "Marco", Date= "16-12-2021"}
}

我尝试使用groupBy,但不起作用

qojgxg4l

qojgxg4l1#

您可以使用日期查找最后一个标题,如下所示:

var last = raw.OrderBy(r => r.Date).Last().Title;

但是,您的数据模型将Date作为字符串,使用的格式不能正确排序。
要使此代码正常工作,您可以选择:

  • 将日期类型更改为DateOnly或DateTime
  • 将日期格式设置为YYYY-MM-DD
  • 按照@yossean-yamil的答案中的建议转换数据类型(比以自然可排序的形式存储效率低)

数据转换替代方案:

// You can use DateOnly instead of DateTime from .NET 6 on
var last = raw
    .Select(r => new 
        { 
            r.Title, 
            Date = DateTime.ParseExact(r.Date, "dd-MM-yyyy", null)
        })
    .OrderBy(r => r.Date).Last().Title;

请注意,由于您的时间分辨率是以天为单位,因此所选标题在共享同一时间戳的所有记录中是不确定的。
如果您希望获得这样一个组中所有标题的列表(请注意,这与日期排序存在相同的问题):

var last = raw
    .GroupBy(r => r.Date)
    .OrderBy(r => r.Key)
    .Last()
    .Select(r => r.Title)
    .ToList();
dy2hfwbg

dy2hfwbg2#

您仍然可以使用GroupBy方法。它将返回IGrouping对象的枚举,该对象也可以被迭代。您需要按Title对数组进行分组,然后按Date对每个组对象按降序排序。

record Register(string Title, DateOnly Date);
public static void Main()
{

    Register[] raw = new[]
    {
        new Register("Sergio", DateOnly.ParseExact("18-12-2021", "dd-MM-yyyy")),
        new Register( "Sergio", DateOnly.ParseExact( "18-10-2021", "dd-MM-yyyy")),
        new Register( "Sergio", DateOnly.ParseExact( "18-11-2021", "dd-MM-yyyy")),
        new Register( "Jose", DateOnly.ParseExact( "19-12-2021", "dd-MM-yyyy")),
        new Register( "Jose", DateOnly.ParseExact( "18-12-2021", "dd-MM-yyyy")),
        new Register( "Jose", DateOnly.ParseExact( "17-12-2021", "dd-MM-yyyy")),
        new Register( "Marco", DateOnly.ParseExact( "16-12-2021", "dd-MM-yyyy"))
    };

    IEnumerable<IGrouping<string, Register>> groups = raw.GroupBy(register => register.Title);

    foreach (IGrouping<string, Register> group in groups)
    {
        string title = group.Key;
        DateOnly? latestDate = group
            .OrderByDescending(register => register.Date)
            .Select(register => register.Date)
            .FirstOrDefault();

        Console.WriteLine("For title {0} the latest date is {1}", title, latestDate);
    }
}

输出量:

For title Sergio the latest date is 12/18/2021
For title Jose the latest date is 12/19/2021
For title Marco the latest date is 12/16/2021
ss2ws0br

ss2ws0br3#

这是一个有点冗长的答案,但在这里我创建了一个类,并使用它来解析,然后使用一个列表,我然后排序和分组位。
请在此处查看运行情况:https://dotnetfiddle.net/Lm12pX
这将生成以下输出:

Hello World
18-10-2021 Group: Sergio January 18, 2021
17-12-2021 Group: Jose January 17, 2021
16-12-2021 Group: Marco January 16, 2021
Overall First one is: 16-12-2021 Marco January 16, 2021

编码:

using System;
using System.Globalization;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        List<Thing> things = new List<Thing>()
        {new Thing{Title = "Sergio", DateCreated = "18-12-2021"}, new Thing{Title = "Sergio", DateCreated = "18-10-2021"}, new Thing{Title = "Sergio", DateCreated = "18-11-2021"}, new Thing{Title = "Jose", DateCreated = "19-12-2021"}, new Thing{Title = "Jose", DateCreated = "18-12-2021"}, new Thing{Title = "Jose", DateCreated = "17-12-2021"}, new Thing{Title = "Marco", DateCreated = "16-12-2021"}};
        foreach (var thing in things.GroupBy(x => x.Title).Select(x => x.OrderBy(x => x.Timestamp).First()))
        {
            Console.WriteLine($"{thing.DateCreated} Group: {thing.Title} {thing.Timestamp.ToString("MMMM dd, yyyy")}");
        }

        var firstThing = things.OrderBy(t => t.Timestamp).First();
        Console.WriteLine($"Overall First one is: {firstThing.DateCreated} {firstThing.Title} " + firstThing.Timestamp.ToString("MMMM dd, yyyy"));
    }

    public class Thing
    {
        public Thing()
        {
        }

        public Thing(string title, string dateCreated)
        {
            Title = title;
            DateCreated = dateCreated;
        }

        public string Title { get; set; }

        public string DateCreated { get; set; }

        public DateTime Timestamp
        {
            get
            {
                CultureInfo provider = CultureInfo.InvariantCulture;
                var format = "dd-mm-yyyy";
                return DateTime.ParseExact(DateCreated, format, provider);
            }
        }
    }
}

相关问题