简体   繁体   English

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

[英]LINQ Problem I want to get the last records of a table for each register

I have this list:我有这个清单:

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

I want a list that contains the last register date for each "Title".我想要一个包含每个“标题”的最后注册日期的列表。 For example, this will be the output:例如,这将是 output:

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

I tried using groupBy but it doesn't work我尝试使用 groupBy 但它不起作用

You can find the last title using the date like this:您可以使用这样的日期找到最后一个标题:

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

However, your data model has Date as a string using a format that doesn't sort properly.但是,您的数据 model 将 Date 作为字符串使用的格式无法正确排序。

For this code to work, you have the options:要使此代码正常工作,您可以选择:

  • Change the type of Date to DateOnly or DateTime将 Date 的类型更改为 DateOnly 或 DateTime
  • Format the date like YYYY-MM-DD格式化日期,如 YYYY-MM-DD
  • Convert the data type as suggested in @yossean-yamil's answer (less efficient than storing it in a naturally sortable form)按照@yossean-yamil 的答案中的建议转换数据类型(效率低于以自然可排序的形式存储)

Data conversion alternative:数据转换替代方案:

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

Note, since your time resolution is to the day, the selected title is non-deterministic among all records sharing the same timestamp.请注意,由于您的时间分辨率是当天,所选标题在共享相同时间戳的所有记录中是不确定的。

If you wish to get a list of all titles in such a group (note this suffers from the same issue with date sorting):如果您希望获得此类组中所有标题的列表(请注意,这与日期排序存在相同的问题):

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

You can still use the GroupBy method.您仍然可以使用 GroupBy 方法。 It will return an enumeration of IGrouping object which can also be iterated.它将返回一个 IGrouping object 的枚举,它也可以被迭代。 You need to group the array by Title, then order by Date in descending order for each group object.您需要按标题对数组进行分组,然后按日期按降序排列每个组 object。

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

Output: Output:

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

A bit of a verbose answer but here I create a class and use that to parse out and then use a list of those which I then order and group a bit.有点冗长的答案,但在这里我创建了一个 class 并使用它来解析,然后使用一个列表,然后我对其进行排序和分组。

See it run here: https://dotnetfiddle.net/Lm12pX看到它在这里运行: https://dotnetfiddle.net/Lm12pX

This produces this output:这将产生这个 output:

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

Code:代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM