0

I have this collection:

[bla1,blubb2,hello3,salve4,adios5,bye6,mucha7,arrividerci8,bonsoir9,hello10,bah11]

I would like to return a collection of T where T has a List with these 3 strings max.

bla1, blubb2, hello3,

salve4, adios5, bye6

mucha7, arrividerci8,bonsoir9

hello10,bah11

These are no 4 objects each having a list with max. 3 items

HelloWorld
  • 4,671
  • 12
  • 46
  • 78

4 Answers4

4

It looks like you want:

List<List<string>> groups = inputList.Select((e, idx) => new { Item = e, Idx = idx })
    .GroupBy(p => p.Idx / 3)
    .Select(grp => grp.Select(p => p.Item).ToList())
    .ToList();
Lee
  • 142,018
  • 20
  • 234
  • 287
2
string[] arr = new[] { "bla1", "blubb2", "hello3", "salve4", "adios5", "bye6", "mucha7", "arrividerci8", "bonsoir9", "hello10", "bah11" };
int cnt=0;
var lists = arr.GroupBy(x => cnt++ / 3)
                .Select(g => g.ToList())
                .ToList();
L.B
  • 114,136
  • 19
  • 178
  • 224
2

You can use MoreLINQ (avalable from NuGet) extension Batch:

string[] source = { "bla1", "blubb2", "hello3", "salve4", "adios5" };
IEnumerable<IEnumerable<string>> result = source.Batch(3);

This extension batches source sequence into sized buckets.

If you don't want to use MoreLINQ library, you can use just their implementation of Batch extension or solution by Timothy.

Community
  • 1
  • 1
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
1

(Use Sergey's answer if you don't mind the MoreLINQ dependency.)

Extension Method

public static IEnumerable<List<T>> GroupSequential<T>(
    this IEnumerable<T> source, int groupSize, bool includePartialGroups = true)
{
    if (groupSize < 1)
    {
        throw new ArgumentOutOfRangeException(
            "groupSize", groupSize, "Must have groupSize >= 1.");
    }
    var group = new List<T>(groupSize);
    foreach (var item in source)
    {
        group.Add(item);
        if (group.Count == groupSize)
        {
            yield return group;
            group = new List<T>(groupSize);
        }
    }
    if (group.Any() && (includePartialGroups || group.Count == groupSize))
    {
        yield return group;
    }
}

Usage

IEnumerable<string> values = ...;
IEnumerable<List<string>> groups = values.GroupSequential(3);
Community
  • 1
  • 1
Timothy Shields
  • 75,459
  • 18
  • 120
  • 173