C# 按特定顺序对值进行分组
我有一个数据列表,需要按特定顺序进行排序和分组。请在下面查找我正在处理的数据:C# 按特定顺序对值进行分组,c#,linq,lambda,C#,Linq,Lambda,我有一个数据列表,需要按特定顺序进行排序和分组。请在下面查找我正在处理的数据: trackId | sectionId | lineId ---------------------------------- 2 | 5 | 210 1 | 1193 | 210 1 | 1192 | 210 1 | 1191 | 210 1 | 987
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
和trackId
对这些数据进行分组,但只能按照它们的顺序进行分组。所以我不能将4x trackId 1和lineId 360分组
这就是我需要的结果:
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**
请注意,一个普通的.GroupBy(g=>new{g.lineId,g.trackId})
如何将lineId 360和trackId 1分为一个组,而实际上我需要两个组
这是我目前得到的结果(这是错误的):
那么,我到底该怎么做呢?我想我可以添加一些ifs和ELSE来实现这一点,但我希望有一些合成糖 您需要使用.ThenBy()
.GroupBy(g=>g.lineId).然后by(x=>x.trackId)
使用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),
};
var数据=新列表
{
(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),
};
我不明白为什么有人投了反对票。如果你至少给我一些反馈,我会更有帮助。边走边用蓄能器。当您点击一个新的轨迹id
时重置。如果每组2个相同的轨迹id都有一个唯一的id,例如带有段id 1193的轨迹id,1192的唯一id为,让我们假设为“1”,然后按lineid分组,唯一id将起作用。但你如何得到唯一的身份证是你的责任。您可以使用临时表生成一些逻辑代码,并在该临时表中插入具有唯一id的数据。最后使用group by TAG调用temp表您可能被否决,因为您没有提供(如代码中所示)。还有,我不知道斯普莱达在这里会有什么帮助。@JorisDecraecker是的,我知道他的意思;)这不是按多个对象分组的方式。尽管尝试得不错,但实际上,ThenBy只适用于IOrderedEnumerable
对象,因此不能在GroupBy()
上使用它,而只能在OrderBy()
上使用。为了可读性,我几乎宁愿在元组中添加另一个属性(在您的例子中)使用do/while
并使用本地的GroupBy
。
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),
};