我尝试为List分配行号和Set号,但是Set Number包含一组中错误的行数。
var objx = new List<x>();
var i = 0;
var r = 1;
objY.ForEach(x => objx .Add(new x
{
RowNumber = ++i,
DatabaseID= x.QuestionID,
SetID= i == 5 ? r++ : i % 5 == 0 ? r += 1 : r
}));
对于像objY这样的上面代码包含23行,我想在5-5集中打破23行。 所以上面的代码会给出像[仅考虑RowNumber ]
这样的序列[1 2 3 4 5][6 7 8 9][ 10 11 12 13 14 ].......
它的逻辑有效 如果我将Setid的逻辑更改为
SetID= i % 5 == 0 ? r += 1 : r
结果会像
一样[1 2 3 4 ][5 6 7 8 9][10 11 12 13 14].
再次纠正代码输出
但预计为5件套。
[1 2 3 4 5][ 6 7 8 9 10].........
我错过了.............
我应该把我的数学课非常认真。
答案 0 :(得分:2)
我想你想要这样的东西:
var objX = objY.Select((x, i) => new { ObjX = x, Index = i })
.GroupBy(x => x.Index / 5)
.Select((g, i) =>
g.Select(x => new objx
{
RowNumber = x.Index + 1
DatabaseID = x.ObjX.QuestionID,
SetID = i + 1
}).ToList())
.ToList();
请注意,我按x.Index / 5
进行分组,以确保每个群组都有5个项目。
<强>更新强>
如果你能解释你的逻辑,它会非常有用
我应该从哪里开始?我正在使用Linq方法来选择原始列表并对其进行分组以创建新的List<List<ObjX>>
,其中每个内部列表最多包含5个元素(如果总计数不能被5分割,则在最后一个中减去)。
Enumerable.Select
可以从输入序列中投射某些内容来创建新内容。此方法与循环中的变量相当。在这种情况下,我投影一个匿名类型与原始对象及其在列表中的索引(Select
具有an overload,其中包含索引)。我创建这个匿名类型只是为了查询,因为我稍后需要在GroupBy``中使用索引。
Enumerable.GroupBy
允许按指定键对序列中的元素进行分组。该键可以是可从元素派生的任何内容。这里我使用索引两个最大大小为5的构建组:
.GroupBy(x => x.Index / 5)
这是有效的,因为C#(或C)中的整数除法总是在int
中,其余部分被截断(与VB.NET btw不同),因此 3/4导致0 。您可以使用此事实来构建指定大小的组。
然后我在组上使用Select
来创建内部列表,再次使用index-overload来设置组的SetId
:
.Select((g, i) =>
g.Select(x => new objx
{
RowNumber = x.Index + 1
DatabaseID = x.ObjX.QuestionID,
SetID = i + 1
}).ToList())
最后一步是使用ToList
上的IEnumerable<List<ObjX>>
创建最终List<List<ObX>>
。这也“实现”了查询。请查看deferred execution,尤其是Jon Skeets blog了解详情。