One way is to build a comparable key out of the pets. For example, this method sorts the pets then combines them into a single string separated by '|'
private static string GetPetKey(Person x)
{
return String.Join("|", x.Pets.OrderBy(y => y).ToArray());
}
A person with the pets: "Spider", "Cat", "Dog"
gets the key: "Cat|Dog|Spider"
Then use that as your LINQ grouping key
var grouped = people.GroupBy(x => GetPetKey(x))
sample implementation:
var people = new List<Person>
{
new Person
{
Id = 1,
Pets = new[] { "Cat", "Dog", "Spider" }
},
new Person
{
Id = 2,
Pets = new[] { "Cat", "Spider", "Snake" }
},
new Person
{
Id = 3,
Pets = new[] { "Dog" }
},
new Person
{
Id = 4,
Pets = new[] { "Spider", "Cat", "Dog" }
},
new Person
{
Id = 5,
Pets = new[] { "Dog" }
}
};
var grouped = people.GroupBy(x => GetPetKey(x)).ToList();
grouped.ForEach(WriteGroup);
output helper
private static void WriteGroup(IGrouping<string, Person> grouping)
{
Console.Write("People with " +String.Join(", ",grouping.First().Pets)+": ");
var people = grouping.Select(x=>"Person "+x.Id).ToArray();
Console.WriteLine(String.Join(", ", people));
}
output:
People with Cat, Dog, Spider: Person 1, Person 4
People with Cat, Spider, Snake: Person 2
People with Dog: Person 3, Person 5