我有一个列表,需要按复杂的排序顺序进行按摩。
我是linq和c#/。net的完全新手(但不是其他语言的编程人员),所以我很想知道我需要朝哪个方向发展。
我的列表(简体)如下:
List[
{nr: 1, originatesFrom: null, lastChanged: DateTime(2018,5,3)},
{nr: 2, originatesFrom: null, lastChanged: DateTime(2018,5,3)},
{nr: 3, originatesFrom: null, lastChanged: DateTime(2018,5,3)},
{nr: 4, originatesFrom: 1, lastChanged: DateTime(2018,5,1)},
{nr: 5, originatesFrom: 2, lastChanged: DateTime(2018,5,1)},
{nr: 6, originatesFrom: 1, lastChanged: DateTime(2018,5,7)},
{nr: 7, originatesFrom: 1, lastChanged: DateTime(2018,5,4)},
{nr: 8, originatesFrom: 3, lastChanged: DateTime(2018,5,13)},
{nr: 9, originatesFrom: 1, lastChanged: DateTime(2018,5,13)},
{nr: 10, originatesFrom: 3, lastChanged: DateTime(2018,5,10)},
{nr: 11, originatesFrom: 3, lastChanged: DateTime(2018,5,18)}
]
我需要将其按摩成这样:
List[
{nr: 5, originatesFrom: 2, lastChanged: DateTime(2018,5,1)},
{nr: 2, originatesFrom: null, lastChanged: DateTime(2018,5,3)},
{nr: 9, originatesFrom: 1, lastChanged: DateTime(2018,5,13)},
{nr: 6, originatesFrom: 1 lastChanged: DateTime(2018,5,7)},
{nr: 7, originatesFrom: 1, lastChanged: DateTime(2018,5,4)},
{nr: 4, originatesFrom: 1, lastChanged: DateTime(2018,5,1)},
{nr: 1, originatesFrom: null, lastChanged: DateTime(2018,5,3)},
{nr: 11, originatesFrom: 3, lastChanged: DateTime(2018,5,18)},
{nr: 8, originatesFrom: 3, lastChanged: DateTime(2018,5,13)},
{nr: 10, originatesFrom: 3, lastChanged: DateTime(2018,5,10)},
{nr: 3, originatesFrom: null, lastChanged: DateTime(2018,5,3)}
]
复杂的排序规则如下:按originsFrom分组,在按lastChanged下降顺序排序的每个组中,按(第一个实例的)lastChanged升序排序的组。最后,在originsFrom中为null的那些应该填充在与它们在originsFrom中的nr相匹配的每个组的底部。 (是的-这不是开箱即用的东西:-/)
我试图通过按originsFrom将它们分组来开始,但是我确实需要将它们拆分为appart,以便我可以对它们进行单独排序(我认为吗?),而且我不确定完全使用linq是不明智的,而不是一次遍历所有对象,而是建立多个列表并最终将它们串联起来?
好的方面是,几乎不会有太多的对象(因此效率可能不是一个大问题)。我不知道要排序多少个组,每个组中有多少个对象。
如果我需要更好地解释排序规则,请告诉我!
答案 0 :(得分:4)
假设这实际上是在List<T>
或类似的语言中(而不是通过IQueryable<T>
,我们可能需要担心查询是否可以翻译),我相信这应该可行:
originatesFrom
(如果非空,否则为nr
”)originatesFrom
(降序)然后按lastChanged
(降序)进行排序-这将在末尾保留originatesFrom
为空lastChanged
”排序列表(升序)SelectMany
这是带有示例输入数据的完整示例:
using System;
using System.Collections.Generic;
using System.Linq;
class Test
{
static void Main()
{
var items = new[]
{
new { Number = 1, OriginatesFrom = (int?) null, LastChanged = new DateTime(2018,5,3) },
new { Number = 2, OriginatesFrom = (int?) null, LastChanged = new DateTime(2018,5,3) },
new { Number = 3, OriginatesFrom = (int?) null, LastChanged = new DateTime(2018,5,3) },
new { Number = 4, OriginatesFrom = (int?) 1, LastChanged = new DateTime(2018,5,1) },
new { Number = 5, OriginatesFrom = (int?) 2, LastChanged = new DateTime(2018,5,1) },
new { Number = 6, OriginatesFrom = (int?) 1, LastChanged = new DateTime(2018,5,7) },
new { Number = 7, OriginatesFrom = (int?) 1, LastChanged = new DateTime(2018,5,4) },
new { Number = 8, OriginatesFrom = (int?) 3, LastChanged = new DateTime(2018,5,13) },
new { Number = 9, OriginatesFrom = (int?) 1, LastChanged = new DateTime(2018,5,13) },
new { Number = 10, OriginatesFrom = (int?) 3, LastChanged = new DateTime(2018,5,10) },
new { Number = 11, OriginatesFrom = (int?) 3, LastChanged = new DateTime(2018,5,18 )}
};
var query = items
.GroupBy(x => x.OriginatesFrom ?? x.Number)
.Select(g => g.OrderByDescending(x => x.OriginatesFrom)
.ThenByDescending(x => x.LastChanged)
.ToList())
.OrderBy(g => g.First().LastChanged)
.SelectMany(g => g)
.ToList();
foreach (var item in query)
{
Console.WriteLine(item);
}
}
}
输出,与您所需的订单相符:
{ Number = 5, OriginatesFrom = 2, LastChanged = 01/05/2018 00:00:00 }
{ Number = 2, OriginatesFrom = , LastChanged = 03/05/2018 00:00:00 }
{ Number = 9, OriginatesFrom = 1, LastChanged = 13/05/2018 00:00:00 }
{ Number = 6, OriginatesFrom = 1, LastChanged = 07/05/2018 00:00:00 }
{ Number = 7, OriginatesFrom = 1, LastChanged = 04/05/2018 00:00:00 }
{ Number = 4, OriginatesFrom = 1, LastChanged = 01/05/2018 00:00:00 }
{ Number = 1, OriginatesFrom = , LastChanged = 03/05/2018 00:00:00 }
{ Number = 11, OriginatesFrom = 3, LastChanged = 18/05/2018 00:00:00 }
{ Number = 8, OriginatesFrom = 3, LastChanged = 13/05/2018 00:00:00 }
{ Number = 10, OriginatesFrom = 3, LastChanged = 10/05/2018 00:00:00 }
{ Number = 3, OriginatesFrom = , LastChanged = 03/05/2018 00:00:00 }
LINQ很棒吗?