gpt4 book ai didi

c# linq 相当复杂的排序

转载 作者:行者123 更新时间:2023-11-30 15:15:20 24 4
gpt4 key购买 nike

我有一个对象列表,我需要整理成一个相当复杂的排序顺序。

我是 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)}
]

复杂的排序规则如下:按 originatesFrom 分组,在每个组内按 lastChanged 降序排序,组按(第一个实例的)lastChanged 升序排序。最后,originatesFrom 中为 null 的那些应该被填充到与它们在 originatesFrom 中的 nr 相匹配的每个组的底部。 (是的 - 它不会是这里开箱即用的东西 :-/)

我试图通过按 originatesFrom 对它们进行分组来开始,但我确实需要将它们分开,以便我可以单独对它们进行排序(我认为?),而且我不确定使用 linq 是否明智,而不是一次一个地遍历所有对象,构建多个列表并最终将它们连接起来?

好处是很少会有真正的对象(所以效率可能不是什么大问题)。在排序之前我不会知道会有多少组,以及每个组中有多少对象。

如果我需要更好地解释排序规则,请告诉我!

最佳答案

假设这实际上是在 List<T> 中或类似的(而不是通过 IQueryable<T> 我们可能需要担心查询是否可以翻译),我相信这应该有效:

  • 分组依据“originatesFrom 如果非空;nr 否则”
  • 将每个组转换成一个列表,在 originatesFrom 上排序(降序)然后按 lastChanged (降序)- 这将保留 null 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 是不是很棒?

关于c# linq 相当复杂的排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52290179/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com