using System.Collections.Generic;
public class PetCategoryOwner
public string PetCategory { get; set; }
public string Owner { get; set; }
public class PetCategoriesOwners
public List<string> PetCategories { get; set; }
public List<string> Owners { get; set; }
public static void Main()
var petCategoryOwner = new List<PetCategoryOwner>()
new PetCategoryOwner { Owner = "Higa", PetCategory = "Terry"},
new PetCategoryOwner { Owner = "Higa", PetCategory = "Charlotte"},
new PetCategoryOwner { Owner = "Oliver", PetCategory = "Terry"},
new PetCategoryOwner { Owner = "Oliver", PetCategory = "Charlotte"},
new PetCategoryOwner { Owner = "Oliver", PetCategory = "Chausie"},
new PetCategoryOwner { Owner = "Price", PetCategory = "Chausie"},
new PetCategoryOwner { Owner = "Liam", PetCategory = "Terry"},
new PetCategoryOwner { Owner = "Liam", PetCategory = "Chartreux"}
var petCategoriesOwners = petCategoryOwner
Categories = x.Select(y => y.PetCategory)
.OrderBy(x => x.Categories.Count())
.Aggregate(new List<PetCategoriesOwners>(), (acc, current) =>
var currentCategories = current.Categories.ToList();
var matches = acc.Where(group => group.PetCategories.All(x => currentCategories.Contains(x)));
foreach(var match in matches)
match.Owners.Add(current.Owner);
currentCategories = currentCategories.Except(match.PetCategories).ToList();
if (currentCategories.Any())
new PetCategoriesOwners() {
Owners = new List<string>() { current.Owner },
PetCategories = currentCategories
foreach(var gr in petCategoriesOwners){
Console.WriteLine(String.Join(",", gr.Owners) + " - " + String.Join(",", gr.PetCategories));