bjarne_f
bjarne_f

Reputation: 105

Split collection into groups of different sizes

I have a collection "cases" (IEnumerable<IPublishedContent>), which I would like to split into chunks like the following, where each second row contains two columns:

<div class="row">
   <div class="col">1</div>
</div>
<div class="row">
   <div class="col">2</div>
   <div class="col">3</div>
</div>
<div class="row">
   <div class="col">4</div>
</div>
<div class="row">
   <div class="col">5</div>
   <div class="col">6</div>
</div>

I have seen different approaches using extension methods, e.g. .Chunk(2), .Batch(2) or .Split(2), but mostly where it is splitted into fixed sizes e.g. [1,2], [3,4], [5,6], [7]

For now I have the following:

var batches = w
            .Select((x, i) => new { x, i })
            .GroupBy(p => (p.i / (p.i % 2 == 0 ? 2 : 1)), p => p.x);

var rows = batches;
var count = 0;
foreach (var row in rows)
{
   <div class="row">
       @foreach (var c in row)
       {
           <div class="col">@(count+1)</div>
           count++;
       }
    </div>
}

When the collection contains 7 elements, the output is:

<div class="row">
   <div class="col">1</div>
</div>
<div class="row">
   <div class="col">2</div>
   <div class="col">3</div>
</div>
<div class="row">
   <div class="col">4</div>
   <div class="col">5</div>
</div>
<div class="row">
   <div class="col">6</div>
</div>
<div class="row">
   <div class="col">7</div>
</div>

Any suggestion how I can get the output as in the first example?

Upvotes: 1

Views: 261

Answers (1)

Ivan Stoev
Ivan Stoev

Reputation: 205629

I believe you can use GroupBy with composite key first to split the input to triples and then to split the triple to pair:

var batches = w.Select((x, i) => new { x, i })
    .GroupBy(e => new { K1 = e.i / 3, K2 = e.i % 3 == 0 ? 0 : 1 })
    .Select(g => g.Select(e => e.x).ToArray())
    .ToList();

Another way would be to produce a single grouping key using the same idea:

.GroupBy(e => 2 * (e.i / 3) + (e.i % 3 == 0 ? 0 : 1))

Upvotes: 2

Related Questions