Предположим 2 класса, Человек и Домашнее животное. У каждого человека есть набор 1 или более домашних животных. Как я группирую Человека в к набору, где они совместно используют тех же домашних животных.
Пример:
Человек 1: CAT, собака, паук
Человек 2: CAT, паук, змея
Человек 3: собака
Человек 4: паук, CAT, собака
Человек 5: собака
Что я хочу, в результате это:
Группа 1: человек 1, человек 4
Группа 2: человек 3, человек 5
Группа 3: человек 2
Как я достигаю этого использования LINQ?
Один из способов - собрать сопоставимый ключ из домашних животных. Например, этот метод сортирует домашних животных, а затем объединяет их в одну строку, разделенную знаком '|'
private static string GetPetKey(Person x)
{
return String.Join("|", x.Pets.OrderBy(y => y).ToArray());
}
Человек с домашними животными: «Паук», «Кошка», «Собака» получает ключ: «Cat | Dog | Spider»
Затем используйте его в качестве ключа группировки LINQ
var grouped = people.GroupBy(x => GetPetKey(x))
. Пример реализации:
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);
вспомогательный модуль вывода
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));
}
вывод:
People with Cat, Dog, Spider: Person 1, Person 4
People with Cat, Spider, Snake: Person 2
People with Dog: Person 3, Person 5