c# – LINQ:从IEnumerable中选择Distinct / GroupBy并进行排序 – 可能吗?

前端之家收集整理的这篇文章主要介绍了c# – LINQ:从IEnumerable中选择Distinct / GroupBy并进行排序 – 可能吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的具体例子相当复杂,但我认为这个概念同样适用于日志记录系统之类的东西,因此为了便于解释,我将使用它.这是一个虚构的例子,请不要对这个例子本身的架构,编程或道德错误进行抨击或痛苦:)

说你有这个:

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

我想要做的是为每个用户选择最后一条记录(即TimeStamp Descending排序)(即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      ",2,02),new LogEntry {ID=3,UserName="bar      ",new LogEntry {ID=4,UserName="sandwich ",3,03),new LogEntry {ID=5,5,05),Details="Stole food      ",new LogEntry {ID=6,Details="Can't find food ",new LogEntry {ID=7,8,08),Details="Donated food    ",new LogEntry {ID=8,9,09),Details="Ate more food   ",new LogEntry {ID=9,Details="Ate food        ",new LogEntry {ID=10,11,11),};

        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#相关文章