1

我试图为 List 分配一个行号和一个 Set-number,但 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].........

我错过了什么......

我应该非常认真地学习我的数学课。

4

1 回答 1

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具有包含索引的重载)。我创建这个匿名类型是为了简单的查询,因为我稍后需要 GroupBy 中的索引。

Enumerable.GroupBy可以通过指定的键对序列中的元素进行分组。这个密钥可以是任何可以从元素派生的东西。在这里,我使用索引两个最大大小为 5 的构建组:

.GroupBy(x => x.Index / 5)

之所以有效,是因为 C#(或 C)中的整数除法总是导致 a int,其中余数被截断(与 VB.NET btw 不同),因此3/4 导致 0。您可以使用此事实来构建指定大小的组。

然后我Select在组上使用创建内部列表,再次使用索引重载来设置SetId组的:

.Select((g, i) => 
    g.Select(x => new objx
    {
        RowNumber = x.Index + 1
        DatabaseID = x.ObjX.QuestionID,
        SetID = i + 1
    }).ToList())

最后一步是使用ToListonIEnumerable<List<ObjX>>创建最终的List<List<ObX>>. 这也“实现”了查询。查看延迟执行,尤其是Jon Skeets 博客以了解更多信息。

于 2013-02-07T16:50:47.310 回答