using System.Collections;
using System.Collections.Generic;
public static void Main()
var products = new List<Product>
new Product(1, "Fruit", "Apple"),
new Product(2, "Fruit", "Banana"),
new Product(3, "Fruit", "Orange"),
new Product(4, "Vegetables", "Carrot"),
new Product(4, "Vegetables", "Pea"),
new Product(3, "Soft Drink", "Orange Juice"),
new Product(2, "Soft Drink", "Lemonade"),
new Product(1, "Alcoholic", "Bitter"),
new Product(1, "Alcoholic", "Lager"),
new Product(2, "Alcoholic", "Vodka")
IEnumerable<GroupResult> groups = products.GroupByMany(x => (x.CategoryId > 2) ? 0 : 1, y => (y.CategoryId < 4) ? 1 : 0);
var primeGroup = groups.GetPrimeGroup();
Console.WriteLine("Result Group: " + primeGroup.Key);
foreach (var item in primeGroup.Items)
public string Name { get; set; }
public int CategoryId { get; set; }
public string Subcategory { get; set; }
public Product(int categoryId, string subcategory, string name)
Subcategory = subcategory;
public override string ToString()
return String.Concat(CategoryId, " => ", Name, " -> ", Subcategory);
public static class IEnumerableExtensions
public static IEnumerable<GroupResult> GroupByMany<TElement>(
this IEnumerable<TElement> elements,
params Func<TElement, int>[] groupSelectors)
if (groupSelectors.Length > 0)
var selector = groupSelectors.First();
var nextSelectors = groupSelectors.Skip(1).ToArray();
elements.GroupBy(selector).Select(
SubGroups = g.GroupByMany(nextSelectors)
public static GroupResult GetPrimeGroup(this IEnumerable<GroupResult> groups)
foreach (var group in groups.OrderBy(x => x.Key))
if (group.SubGroups != null && group.SubGroups.Count() > 0)
return group.SubGroups.GetPrimeGroup();
public IEnumerable<GroupResult> SubGroups
public override string ToString()
return string.Format("{0} ({1})", Key, Count);