按包含元素的日期(LINQ)对组进行排序以显示它们

按包含元素的日期(LINQ)对组进行排序以显示它们,linq,sorting,linq-group,Linq,Sorting,Linq Group,我不确定这是否可行。 我的班级我有一个如下列表: class Person { string Firstname string Lastname DateTime Timestamp } PersonGroups= persons.OrderByDescending(p => p.Timestamp) .GroupConsecutive(p => new Header(p.Firstname, p.Lastname)); 现在我想通过名字和姓

我不确定这是否可行。 我的班级我有一个如下列表:

class Person
{
 string Firstname
 string Lastname
 DateTime Timestamp
}
PersonGroups= persons.OrderByDescending(p => p.Timestamp)
                .GroupConsecutive(p => new Header(p.Firstname, p.Lastname));
现在我想通过名字和姓氏创建组

  • 约翰·迪尔,3:12
  • 约翰·迪尔,6:34
  • 约翰·迪尔,11:12
  • 汤姆金,1:12
  • 汤姆金,3:49
  • 汤姆金,4:22
  • 马库斯·弗特,11:23
此外,我还想按时间戳对这些组进行排序,最后一个应该是第一个,而组应该保留在列表视图中显示它们

  • 马库斯·弗特(组头)
    11:23(内容元素)

  • 约翰迪尔
    11:12
    6:34

  • 汤姆金
    4:22
    3:49

  • 约翰迪尔
    3:12

  • 汤姆金
    1:22

希望任何Linq天才都能帮我解决这个问题:) 谢谢


非常感谢谢尔盖,他工作得很有魅力

此外,我想为我的组键创建一个自定义类,以便在我的ListView标题中显示不同的附加内容。(不仅仅是拼接在一起的串)

我想将我的查询分配给IEnumerable,如下所示:

IEnumerable<IGrouping<Header, Person>> PersonGroups 

实际上,您需要先按时间戳对结果进行排序。然后才按连续的人对这个顺序进行分组:

var query = 
  people.OrderByDescending(p => p.Timestamp.TimeOfDay)
        .GroupConsecutive(p => String.Format("{0} {1}", p.Firstname, p.Lastname))
        .Select(g => new {
             Header = g.Key,
             Content = String.Join("\n", g.Select(p => p.Timestamp.TimeOfDay))
        });
您将需要实现,它基于提供的选择器的相同值(您的示例中为全名)创建连续项组

对于您的示例,输入结果为:

[
  {
    "Header": "Markus Fert",
    "Content": "11:23:00"
  },
  {
    "Header": "John Deer",
    "Content": "11:12:00\n06:34:00"
  },
  {
    "Header": "Tom Kin",
    "Content": "04:22:00\n03:49:00"
  },
  {
    "Header": "John Deer",
    "Content": "03:12:00"
  },
  {
    "Header": "Tom Kin",
    "Content": "01:12:00"
  }
]

下面是一种使用内置链接操作符
Aggregate
的方法

首先,我需要按时间戳降序排列列表,然后我创建了一个名称格式化程序函数

var op = people
    .OrderByDescending(p => p.Timestamp)
    .ToArray();

Func<Person, string> toName = p =>
    String.Format("{0} {1}", p.Firstname, p.Lastname);
var op=people
.OrderByDescending(p=>p.Timestamp)
.ToArray();
Func toName=p=>
格式(“{0}{1}”,p.Firstname,p.Lastname);
现在,我可以构建查询:

var query =
    op
        .Skip(1)
        .Aggregate(new []
        {
            new
            {
                Name = toName(op.First()),
                Timestamps = new List<string>()
                {
                    op.First().Timestamp.ToShortTimeString(),
                },
            },
        }.ToList(), (a, p) =>
        {
            var name = toName(p);
            if (name == a.Last().Name)
            {
                a.Last().Timestamps.Add(p.Timestamp.ToShortTimeString());
            }
            else
            {
                a.Add(new
                {
                    Name = name,
                    Timestamps = new List<string>()
                    {
                        p.Timestamp.ToShortTimeString(),
                    },
                });
            }
            return a;
        });
var查询=
op
.Skip(1)
.合计(新[]
{
新的
{
Name=toName(op.First()),
时间戳=新列表()
{
op.First().Timestamp.ToShortTimeString(),
},
},
}.ToList(),(a,p)=>
{
变量名称=toName(p);
if(name==a.Last().name)
{
a、 Last().Timestamp.Add(p.Timestamp.ToShortTimeString());
}
其他的
{
a、 添加(新)
{
Name=Name,
时间戳=新列表()
{
p、 Timestamp.ToShortTimeString(),
},
});
}
返回a;
});
我得到了这个结果:


哇,那太棒了!谢谢Sergey,很有魅力,我现在有了我需要的团队。我还有一个问题——编辑我的问题。也许你也能帮我?不过还是非常感谢你@sust86如果您想要
i分组
而不是
i分组
,那么只需使头类实现IComparable即可-默认比较器需要比较分组键NeverMind,更正了我的个人组IComparable中的一个错误。谢谢
var query =
    op
        .Skip(1)
        .Aggregate(new []
        {
            new
            {
                Name = toName(op.First()),
                Timestamps = new List<string>()
                {
                    op.First().Timestamp.ToShortTimeString(),
                },
            },
        }.ToList(), (a, p) =>
        {
            var name = toName(p);
            if (name == a.Last().Name)
            {
                a.Last().Timestamps.Add(p.Timestamp.ToShortTimeString());
            }
            else
            {
                a.Add(new
                {
                    Name = name,
                    Timestamps = new List<string>()
                    {
                        p.Timestamp.ToShortTimeString(),
                    },
                });
            }
            return a;
        });