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

时间:2014-10-01 09:05:13

标签: c# linq

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

对象有三个属性: 事件名称 开始 端

我给出了一个事件的名称" EventName"以及所述事件的开始/结束时间,并填充List。

现在是困难的部分。

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

例如:

列表(0):

EventName:测试2 开始:上午10点 结束:下午3点

列表(1):

EventName:测试2 开始:上午10点 结束:上午11点

列表(2):

EventName:测试1 开始时间:中午12点 结束:下午1点

列表(3):

EventName:测试2 开始时间:下午2点 结束:下午3点

因此,当完成所有操作后,需要将List排序为:

列表(0):

EventName:测试2 开始:上午10点 结束:上午11点

列表(1):

EventName:测试2 开始:上午10点 结束:下午3点

列表(2):

EventName:测试2 开始时间:下午2点 结束:下午3点

列表(3):

EventName:测试1 开始时间:中午12点 结束:下午1点

我真的不知道该怎么做。我有这么多没有用的东西:

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

任何帮助都将不胜感激。

修改 为了更容易,假设时间在24小时内转换并存储为整数,因为我可以很容易地做到这一点。

3 个答案:

答案 0 :(得分:2)

我相信我拥有它!

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

到目前为止,这是我需要的代码:

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

如果所有其他建议都失败了,那就是在按开始时间排序时将EventNames组合在一起。

_

答案 1 :(得分:0)

没有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;
             });

改编自Sort a list by Code, Then by Name的解决方案。未经测试。特别是return语句可能需要一些操作。用您作为List对象使用的任何内容替换事件。

答案 2 :(得分:0)

您需要将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)