c# - 从具有 Distinct/GroupBy 的 IEnumerable 中选择并排序——可能吗?

标签 c# .net vb.net linq distinct

假设你有这个:

class LogEntry
{
    int ID;
    int UserName;
    datetime TimeStamp;
    string Details;
}

并且您已经提取了一组这样的数据:

ID  Username   Timestamp   Details
1   foo        1/01/2010   Account created
2   zip        2/02/2010   Account created
3   bar        2/02/2010   Account created
4   sandwich   3/03/2010   Account created
5   bar        5/05/2010   Stole food
6   foo        5/05/2010   Can't find food
7   sandwich   8/08/2010   Donated food
8   sandwich   9/09/2010   Ate more food
9   foo        9/09/2010   Ate food
10  bar        11/11/2010  Can't find food

我想要做的是只为每个用户(即 GroupBy 用户名)选择最后一条记录(即按时间戳降序排序)。我可以理解 Distinct 和 GroupBy,但是将它们组合在一个语句中,该语句还返回非不同/分组的字段/属性并按时间戳排序,这让我很头疼。

上面的例子应该得出的结果是:

ID  Username   Timestamp   Details
2   zip        2/02/2010   Account created
8   sandwich   9/09/2010   Ate more food
9   foo        9/09/2010   Ate food
10  bar        11/11/2010  Can't find food

当我确信可以在单个 LINQ 语句中完成时,我不想“作弊”并诉诸冗长的方法。

最佳答案

希望我的 Linq-fu 是正确的:=)

var results = sourceList
    .OrderByDescending(item => item.Timestamp)
    .GroupBy(item => item.Username)
    .Select(grp => grp.First())
    .ToArray();

此示例代码使用您的数据,并按 ID 最终排序,提供与您的示例完全相同的输出:(如果您不介意粗略的格式!)

class Program
{
    static void Main(string[] args)
    {
        var sourceItems = new[] {
            new LogEntry {ID=1   ,UserName="foo      ", TimeStamp= new DateTime(2010 ,1,01),Details="Account created ",}    ,
            new LogEntry {ID=2   ,UserName="zip      ", TimeStamp= new DateTime(2010 ,2,02),Details="Account created ",}    ,
            new LogEntry {ID=3   ,UserName="bar      ", TimeStamp= new DateTime(2010 ,2,02),Details="Account created ",}    ,
            new LogEntry {ID=4   ,UserName="sandwich ", TimeStamp= new DateTime(2010 ,3,03),Details="Account created ",}    ,
            new LogEntry {ID=5   ,UserName="bar      ", TimeStamp= new DateTime(2010 ,5,05),Details="Stole food      ",}    ,
            new LogEntry {ID=6   ,UserName="foo      ", TimeStamp= new DateTime(2010 ,5,05),Details="Can't find food ",}    ,
            new LogEntry {ID=7   ,UserName="sandwich ", TimeStamp= new DateTime(2010 ,8,08),Details="Donated food    ",}    ,
            new LogEntry {ID=8   ,UserName="sandwich ", TimeStamp= new DateTime(2010 ,9,09),Details="Ate more food   ",}    ,
            new LogEntry {ID=9   ,UserName="foo      ", TimeStamp= new DateTime(2010 ,9,09),Details="Ate food        ",}    ,
            new LogEntry {ID=10  ,UserName="bar      ", TimeStamp= new DateTime(2010,11,11),Details="Can't find food ",}    ,
        };

        var results = sourceItems
            .OrderByDescending(item => item.TimeStamp)
            .GroupBy(item => item.UserName)
            .Select(grp => grp.First())
            .OrderBy(item=> item.ID)
            .ToArray();

        foreach (var item in results)
        {
            Console.WriteLine("{0} {1} {2} {3}",
                item.ID, item.UserName, item.TimeStamp, item.Details);
        }
        Console.ReadKey();
    }
}


public class LogEntry
{
    public int ID;
    public string UserName;
    public DateTime TimeStamp;
    public string Details;
}

关于c# - 从具有 Distinct/GroupBy 的 IEnumerable 中选择并排序——可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3965464/

相关文章:

MySQL 登录对我有用,但对我使用 VB 的 friend 不行

c# - 数学公式在 C# 中的答案与在 Excel 或计算器中的答案不同

c# - 在后台应用程序中读取字符

c++ - 错误 C2653。在 C++ 中找不到类型或命名空间名称(存在引用)

.net - 如何循环遍历一个类的所有属性?

c# - 有人使用 .NET 的 System.IO.IsolatedStorage 吗?

c# - 将用户定义的函数添加到 Visual Studio Excel 加载项

C# Property get set 不设置值

c# - 为什么按钮同时支持 RoutedEvent 和命令?

c# - 在代码中设置 Entity Framework 的凭据,不使用 Integrated Security 并且仅将用户 ID 存储在配置文件中