说你有这个:
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语句中完成时,我会采用冗长的方式来做这件事。
答案 0 :(得分:19)
希望我的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;
}