按多个属性对对象列表进行排序和分组

本文关键字:排序 列表 属性 对象 | 更新日期: 2023-09-27 18:25:07

我有一个复杂的排序/分组,需要使用对象列表来执行。

这些对象有三个特性:事件名称开始结束

我会得到一个事件的名称"EventName"和该事件的开始/结束时间,并填充一个列表。

现在是困难的部分。

要求是:-同一EventName可以有多个开始/结束时间不同的条目-事件将按开始时间排序,最早的事件将首先发生-如果事件的开始时间相同,则应按最短到最长的运行时间进行排序。-然后对事件进行分组,因此所有具有相同名称的事件都以升序列在事件名称下。-具有不同名称但总体最早开始时间相同的事件将按字母顺序排序。

例如:

列表(0):

事件名称:测试2开始时间:上午10点结束:下午3点

列表(1):

事件名称:测试2开始时间:上午10点结束:上午11点

列表(2):

事件名称:测试1开始时间:中午12点结束:下午1点

列表(3):

事件名称:测试2开始时间:下午2点结束:下午3点

因此,当一切都说了算,列表需要排序为:

列表(0):

事件名称:测试2开始时间:上午10点结束:上午11点

列表(1):

事件名称:测试2开始时间:上午10点结束:下午3点

列表(2):

事件名称:测试2开始时间:下午2点结束:下午3点

列表(3):

事件名称:测试1开始时间:中午12点结束:下午1点

我真的不知道该怎么做。我有这么多不起作用:

theList.OrderBy(o => o.Start).ThenBy(o => o.End).ThenBy(o => o.EventName);

如有任何帮助,我们将不胜感激。

编辑为了更容易,假设时间转换为24小时时间,并存储为int,因为我可以很容易地做到这一点。

按多个属性对对象列表进行排序和分组

我相信我有它!

只是对我已经有的东西做了一些小调整。

这是迄今为止我需要的代码:

theList.GroupBy(o => o.EventName).Select(s => s.OrderBy(a => a.Start).ThenBy(a => a.End)).SelectMany(sm => sm).ToList();

所有其他建议的失败之处在于,在按开始时间排序时,将EventNames分组在一起。

_

没有Linq:的解决方案

theList.Sort(delegate(Event p1, Event p2)
             {
                   var byStart = p1.Start.CompareTo(p2.Start);
                   var byEnd = p1.End.CompareTo(p2.End);
                   var byEventName = p1.EventName.CompareTo(p2.EventName);
                   return byStart == 0 ? byEnd == 0 ? byEventName : byEnd : byStart;
             });

解决方案改编自按代码排序列表,然后按名称排序。未测试。特别是return语句可能需要一些操作。将Event替换为用作List对象的任何对象。

您需要将StartEnd存储到没有am和pm的临时变量中,然后对这些数字执行排序操作假设具有这三个属性的类名是Event,那么这里是linq语句

list.Select(s => new
 {
    EventName = s.EventName,
    Start = s.Start,
    End = s.End,
    // getting number without am/pm and where it is pm adding 12
    NumberStart = s.Start.EndsWith("pm") ?
                    12 + Convert.ToInt32(s.Start.Trim('m').TrimEnd('p')) : 
                         Convert.ToInt32(s.Start.Trim('m').TrimEnd('a')),
    NumberEnd = s.End.EndsWith("pm") ?
                    12 + Convert.ToInt32(s.End.Trim('m').TrimEnd('p')) :
                         Convert.ToInt32(s.End.Trim('m').TrimEnd('a'))
 }).OrderBy(s => s.NumberStart)
   .ThenBy(s => s.NumberEnd - s.NumberStart)
   .ThenBy(s => s.EventName)
   .Select(s => new Event { EventName = s.EventName, Start = s.Start, End = s.End });

编辑

尝试将OrderBy序列更改为

.OrderBy(s => s.EventName)
   .ThenBy(s => s.NumberStart)
   .ThenBy(s => s.NumberEnd - s.NumberStart)