You could project the group number onto each item in the original list using Select
and an anonymous type like this:
var assigned = Class.Students.Select(
(item, index) => new
{
Student = item,
GroupNumber = index / 20 + 1
});
Then you can use it like this:
foreach (var item in assigned)
{
Console.WriteLine("Student = " + item.Student.Name);
Console.WriteLine("You belong to Group " + item.GroupNumber.ToString());
}
Or if you wanted to pick off a particular group.
foreach (var student in assigned.Where(x => x.GroupNumber == 5))
{
Console.WriteLine("Name = " + student.Name);
}
Or if you wanted to actually group them to perform aggregates
foreach (var group in assigned.GroupBy(x => x.GroupNumber))
{
Console.WriteLine("Average age = " + group.Select(x => x.Student.Age).Average().ToString());
}
Now if you just want to lump the items in batches and you do not care about having the batch number information you can create this simple extension method.
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> target, int size)
{
var assigned = target.Select(
(item, index) => new
{
Value = item,
BatchNumber = index / size
});
foreach (var group in assigned.GroupBy(x => x.BatchNumber))
{
yield return group.Select(x => x.Value);
}
}
And you could use your new extension method like this.
foreach (var batch in Class.Students.Batch(20))
{
foreach (var student in batch)
{
Console.WriteLine("Student = " + student.Name);
}
}