Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 按特定顺序对值进行分组_C#_Linq_Lambda - Fatal编程技术网

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),
};