c# linq GroupBy для значений списка в списке - PullRequest
7 голосов
/ 12 февраля 2020

У меня есть список объектов, а внутри объекта есть список строк. Что я хочу сделать, это выяснить, сколько из каждого строкового значения существует.

Итак, чтобы создать простой пример с языками, на которых говорят люди в команде.

public class PeopleLanguages
{
    public string Name;
    public List<string> Languages;
}

Создайте тестовые данные ...

List<PeopleLanguages> peopleLanguages = new List<PeopleLanguages>();

peopleLanguages.Add(new PeopleLanguages { Name = "Rod", Languages = new List<string> { "English", "French", "German" } });
peopleLanguages.Add(new PeopleLanguages { Name = "Jane", Languages = new List<string> { "English", "Spanish", "Greek" } });
peopleLanguages.Add(new PeopleLanguages { Name = "Fredie", Languages = new List<string> { "French", "Arabic", "Italian" } });
peopleLanguages.Add(new PeopleLanguages { Name = "Viktor", Languages = new List<string> { "English", "Krakozhian" } });

Для визуализации данных:

 * Rod => English | French | German
 * Jane => English | Spanish | Greek
 * Fredie => French | Arabic | Italian
 * Viktor => English | Krakozhian

Я могу получить желаемый результат, найдя различные строковые значения, используя SelectMany().Distinct(), затем сопоставив их в foreach. l oop:

foreach (string language in peopleLanguages.SelectMany(p => p.Languages).Distinct())
{
    Console.WriteLine($"{language} = {peopleLanguages.Where(p => p.Languages.Contains(language)).Count()}");
}

Вывод:

English = 3
French = 2
German = 1
Spanish = 1
Greek = 1
Arabic = 1
Italian = 1
Krakozhian = 1

Но должен быть лучший способ сделать это, используя GroupBy().

Я просто застрял в том, как извлечь отдельные значения из списка языков.

1 Ответ

8 голосов
/ 12 февраля 2020

Демонстрация при выполнении tnet fiddle

Вы можете использовать SelectMany, чтобы получить список языков списка, затем GroupBy, когда вы будете sh как показано ниже

var result = peopleLanguages
    .SelectMany(p => p.Languages)
    .GroupBy(p => p);

foreach(var item in result)
{
    Console.WriteLine($"{item.Key} : {item.Count()}");
}

Выход

English : 3
French : 2
German : 1
Spanish : 1
Greek : 1
Arabic : 1
Italian : 1
Krakozhian : 1
...