First group entirely:
[
{ "A": [person1, person2, person3] },
{ "B": [person4, person5, person6] }
]
Then partition it into chunks in a second pass. In your case you want to create an entire group object for each element of the partition. This will require some SelectMany cleverness to recreate a group. GroupBy the person's group again will recover the key and create a new group.
[
[
{ "A": [person1, person2] },
{ "A": [person3] }
],
[
{ "B": [person4, person5] },
{ "B": [person6] }
]
]
And also in the second pass, you can use SelectMany to flatten it.
[
{ "A": [person1, person2] },
{ "A": [person3] },
{ "B": [person4, person5] },
{ "B": [person6] }
]
Here is the critical part. Chunk is included in the complete example below:
var query = people.GroupBy(person => person.Group)
.SelectMany(g => g.Chunk(2))
.SelectMany(g => g.GroupBy(person => person.Group));
Here is a complete example.
using System;
using System.Collections.Generic;
using System.Linq;
public class Person
{
public string Name { get; set; }
public string Group { get; set; }
public override string ToString()
{
return string.Format("{0} ({1})", Name, Group);
}
}
public static class Extensions
{
public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source, int chunksize)
{
while (source.Any())
{
yield return source.Take(chunksize);
source = source.Skip(chunksize);
}
}
}
class Program
{
static void Main(string[] args)
{
Person[] people = new Person[] {
new Person() { Name = "person1", Group = "A" },
new Person() { Name = "person2", Group = "A" },
new Person() { Name = "person3", Group = "A" },
new Person() { Name = "person4", Group = "B" },
new Person() { Name = "person5", Group = "B" },
new Person() { Name = "person6", Group = "B" }
};
var query = people.GroupBy(person => person.Group)
.SelectMany(g => g.Chunk(2))
.SelectMany(g => g.GroupBy(person => person.Group));
foreach (var group in query)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine(" {0}", item);
}
}
}
}