Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I segment the elements iterated over in a foreach loop

Tags:

c#

foreach

linq

I need to loop through an entire list of users, but need to grab 20 at a time.

foreach (var student in Class.Students.Take(20))
{
   Console.WriteLine("You belong to Group " + groupNumber);
   groupNumber++;
}

This way the first 20 will belong to Group 1, the second 20 to Group 2, and so on.

Is Take the correct syntax for this? I believe Take will take 20 then be done. Thanks!

like image 201
Hairgami_Master Avatar asked Jul 27 '11 18:07

Hairgami_Master


2 Answers

You can do something like this:

int i = 0;
foreach (var grouping in Class.Students.GroupBy(s => ++i / 20))
    Console.WriteLine("You belong to Group " + grouping.Key.ToString());
like image 140
MikeP Avatar answered Oct 06 '22 18:10

MikeP


For a similar problem I once made an extension method:

public static IEnumerable<IEnumerable<T>> ToChunks<T>(this IEnumerable<T> enumerable, int chunkSize)
{
    int itemsReturned = 0;
    var list = enumerable.ToList(); // Prevent multiple execution of IEnumerable.
    int count = list.Count;
    while (itemsReturned < count)
    {
        int currentChunkSize = Math.Min(chunkSize, count - itemsReturned);
        yield return list.GetRange(itemsReturned, currentChunkSize);
        itemsReturned += currentChunkSize;
    }
}

Note that the last chunk may be smaller than the specified chunk size.

EDIT The first version used Skip()/Take(), but as Chris pointed out, GetRange is considerably faster.

like image 35
Gert Arnold Avatar answered Oct 06 '22 19:10

Gert Arnold