我有一个需要排序的数据列表,并需要按照特定的顺序进行分组。在下面找到我正在使用的数据:
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 })
那么,我到底该如何实现呢?我想我可以添加一些假设来实现它,但是我希望有一些合成糖。
答案 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)