按特定顺序分组值

时间:2018-08-17 12:49:10

标签: c# linq lambda

我有一个需要排序的数据列表,并需要按照特定的顺序进行分组。在下面找到我正在使用的数据:

from threading import Timer
import time

class RepeatingTimer:
    def __init__(self, period, method, args):
        self.stopped = False
        self.args = args
        self.method = method
        self.period = period
        self.task = None

    def schedule(self):
        if not self.stopped:
            self.task = Timer(self.period, self.run, [])
            self.task.start()
    def run(self):
        if not self.stopped:
            self.method(*self.args)
            self.schedule()
    def stop(self):
        self.stopped = True
        if self.task:
            self.task.cancel()
            self.task.join()

    def start(self):
        self.schedule()

def something(a, b):
    print(a + b)

timmy = RepeatingTimer(0.5, something, (5,6))
timmy.start()

time.sleep(1)
timmy.stop()

我需要找到一种方法来按 trackId | sectionId | lineId ---------------------------------- 2 | 5 | 210 1 | 1193 | 210 1 | 1192 | 210 1 | 1191 | 210 1 | 987 | 360 1 | 988 | 360 2 | 986 | 360 1 | 985 | 360 1 | 1189 | 360 lineId对数据进行分组,但只能按顺序进行。因此,我无法将4x trackId 1和lineId 360分组。

这是我需要的结果:

trackId

请注意,普通的lineId = 210, trackId = 2, sectionId = 5 lineId = 210, trackId = 1, sectionId = 1193, 1192, 1191 **lineId = 360, trackId = 1, sectionId = 987, 988** lineId = 360, trackId = 2, sectionId = 986 **lineId = 360, trackId = 1, sectionId = 985, 1189** 会将lineId 360和trackId 1分为1组,而实际上我需要两组。

这是我当前得到的结果(这是错误的):

.GroupBy(g => new { g.lineId, g.trackId })

那么,我到底该如何实现呢?我想我可以添加一些假设来实现它,但是我希望有一些合成糖。

2 个答案:

答案 0 :(得分:0)

使用linq的一种方法是:

var list = data.Select((item, index) => (item, index));
var group = 1;
var result = (from prev in list
              join curr in list on prev.index + 1 equals curr.index into j
              from curr in j.DefaultIfEmpty()
              select (prev.item, curr.item.trackId == prev.item.trackId && curr.item.lineId == prev.item.lineId ? @group : @group++) into s
              group s.item.sectionId by (s.Item2, s.item.trackId, s.item.lineId) into g
              select new { g.Key.trackId, g.Key.lineId, sectionIds = g.ToList() }).ToList();

基本上,它将每个项目与其后一个项目结合在一起,如果两个字段匹配,则给出分组编号。然后根据需要对字段和分组顺序进行分组。


为方便起见,我使用命名元组并像这样初始化数据:

var data = new List<(int trackId, int sectionId, int lineId)>
{
    (2, 5, 210),
    (1, 1193, 210),
    (1, 1192, 210),
    (1, 1191, 210),
    (1, 987, 360),
    (1, 988, 360),
    (2, 986, 360),
    (1, 986, 360),
    (1, 1189, 360),
};

答案 1 :(得分:-1)

您需要使用.ThenBy() .GroupBy(g => g.lineId).ThenBy(x => x.trackId)