我有一个复杂的排序/分组需要使用对象列表来执行。
对象有三个属性: 事件名称 开始 端
我给出了一个事件的名称" EventName"以及所述事件的开始/结束时间,并填充List。
现在是困难的部分。
要求是: - 相同的EventName可以有多个具有不同开始/结束时间的条目 - 事件按开始时间排序,最早出现 - 事件,如果它们具有相同的开始时间,则应按最短到最长的运行时间排序。 - 然后将事件分组,因此具有相同名称的所有事件将按事件名称下的升序列出。 - 具有不同名称但总体最早开始时间相同的事件将按字母顺序排序。
例如:
EventName:测试2 开始:上午10点 结束:下午3点
EventName:测试2 开始:上午10点 结束:上午11点
EventName:测试1 开始时间:中午12点 结束:下午1点
EventName:测试2 开始时间:下午2点 结束:下午3点
因此,当完成所有操作后,需要将List排序为:
EventName:测试2 开始:上午10点 结束:上午11点
EventName:测试2 开始:上午10点 结束:下午3点
EventName:测试2 开始时间:下午2点 结束:下午3点
EventName:测试1 开始时间:中午12点 结束:下午1点
我真的不知道该怎么做。我有这么多没有用的东西:
theList.OrderBy(o => o.Start).ThenBy(o => o.End).ThenBy(o => o.EventName);
任何帮助都将不胜感激。
修改 为了更容易,假设时间在24小时内转换并存储为整数,因为我可以很容易地做到这一点。
答案 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)
您需要将Start
和End
存储到临时变量中,而不是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)