1

i trying to assign a row number and a Set-number for List, but Set Number containing wrong number of rows in one set.

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

for Above code like objY Contains 23 rows, and i want to break 23 rows in 5-5 set. so above code will give the sequence like[Consider only RowNumber]

[1 2 3 4 5][6 7 8 9][ 10 11 12 13 14 ].......

its a valid as by the logic and if i change the logic for Setid as

 SetID= i % 5 == 0 ? r += 1 : r

Result Will come Like

[1 2 3 4 ][5 6 7 8 9][10 11 12 13 14].

Again correct output of code

but expected for set of 5.

[1 2 3 4 5][ 6  7 8 9 10].........

What i missing.............

i should have taken my Maths class very Serious.

joshua
  • 2,371
  • 2
  • 29
  • 58

1 Answers1

2

I think you want something like this:

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();

Note that i'm grouping by x.Index / 5 to ensure that every group has 5 items.

Here's a demo.

Update

it will be very helpful,if you can explain your logic

Where should i start? I'm using Linq methods to select and group the original list to create a new List<List<ObjX>> where every inner list has maximum 5 elements(less in the last if the total-count is not dividable by 5).

Enumerable.Select enables to project something from the input sequence to create something new. This method is comparable to a variable in a loop. In this case i project an anonymous type with the original object and the index of it in the list(Select has an overload that incorporates the index). I create this anonymous type to simply the query and because i need the index later in the GroupBy``.

Enumerable.GroupBy enables to group the elements in a sequence by a specified key. This key can be anything which is derivable from the element. Here i'm using the index two build groups of a maximum size of 5:

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

That works because integer division in C# (or C) results always in an int, where the remainder is truncated(unlike VB.NET btw), so 3/4 results in 0. You can use this fact to build groups of the specified size.

Then i use Select on the groups to create the inner lists, again by using the index-overload to be able to set the SetId of the group:

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

The last step is using ToList on the IEnumerable<List<ObjX>> to create the final List<List<ObX>>. That also "materializes" the query. Have a look at deferred execution and especially Jon Skeets blog to learn more.

Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939