根据类成员C#

时间:2017-07-19 00:02:35

标签: c# list linq group-by distinct

我有一个Person类,如下所示:

public class Person
{
    public Person() { }
    public Person(string name, int age, GenderType gender, string country) { Name = name; Age = age; Gender = gender; Country = country; }

    public string Name { get; set; }
    public int Age { get; set; }
    public GenderType Gender { get; set; } // GenderType = M/F
    public string Country { get; set; }
}

我想首先根据性别将此列表分为两个列表。然后我想进一步将每个列表划分为基于Country的子列表。因此,如果我在原始列表中有n个不同的国家/地区,那么我最终会得到n到2n个列表。以下示例将进一步说明这一想法:

说我的原始列表是这样的:

Sam, 23, M, USA
Jon, 13, M, USA
Jen, 26, F, USA
Thilini, 25, F, Sri Lanka
Anna, 23, F, UK
Chelsea, 35, F, UK
Saman, 43, M, Sri Lanka
Dan, 27, M, UK

第一师:

Male lists:
Sam, 23, M, USA
Jon, 13, M, USA
Saman, 43, M, Sri Lanka
Dan, 27, M, UK

------------------

Female lists:
Jen, 26, F, USA
Thilini, 25, F, Sri Lanka
Anna, 23, F, UK
Chelsea, 35, F, UK

然后进一步细分列表:

Male sub-list 1:
Sam, 23, M, USA
Jon, 13, M, USA

Male sub-list 2:
Saman, 43, M, Sri Lanka

Male sub-list 3:
Dan, 27, M, UK

------------------

Female sub-list 1:
Jen, 26, F, USA

Female sub-list 2:
Thilini, 25, F, Sri Lanka

Female sub-list 3:
Anna, 23, F, UK
Chelsea, 35, F, UK

我可以使用foreach循环轻松地完成此操作,并可能使用Results类来浏览每个项目。但我想学习如何使用Linq GroupBy()和也许Distinct()?

我使用GroupBy()将其分为两个基于性别的列表,如下所示。

static void Main(string[] args)
{
    List<Person> people = new List<Person>()
    {
        new Person("Sam", 23, GenderType.M, "USA"),
        new Person("Jon", 13, GenderType.M, "USA"),
        new Person("Jen", 26, GenderType.F, "USA"),
        new Person("Thilini", 25, GenderType.F, "Sri Lanka"),
        new Person("Anna", 23, GenderType.F, "UK"),
        new Person("Chelsea", 35, GenderType.F, "UK"),
        new Person("Saman", 43, GenderType.M, "Sri Lanka"),
        new Person("Dan", 27, GenderType.M, "UK")
    };

    var maleList = people.GroupBy(x => x.Gender).Where(y => y.Key == GenderType.M);
    var femaleList = people.GroupBy(x => x.Gender).Where(y => y.Key == GenderType.F);

    Console.ReadLine();
}

我不明白我如何根据Country再次将每个列表细分为多个。

2 个答案:

答案 0 :(得分:5)

只需按组合键进行分组:

var groups = people.GroupBy(p => new { p.Gender, p.Country });

然后您可以迭代组并显示结果:

foreach(var group in groups.OrderBy(g => g.Key.Gender).ThenBy(g => g.Key.Country))
{
    Console.WriteLine($"{group.Key.Gender} sub list {group.Key.Country}");

    foreach(var person in group)
        Console.WriteLine($"{person.Name} {person.Age} {person.Gender} {person.Country}");
}

答案 1 :(得分:3)

  

我事先并不知道我的列表中可能包含的国家/地区,那么我应该用什么来分组?

GroupBy()方法并不关心您是否事先知道可能的值是什么。您可以提供任何等值键,它将在该键上生成组的枚举。

听起来你需要帮助的不是分组,而是如何表示结果。有很多不同的方法可以做到,所以问题可能过于宽泛。但是恕我直言,存储根据密钥分组的数据的最有用的方法之一是在字典中。在您的示例中,看起来像这样:

static void Main(string[] args)
{
    List<Person> people = new List<Person>()
    {
        new Person("Sam", 23, GenderType.M, "USA"),
        new Person("Jon", 13, GenderType.M, "USA"),
        new Person("Jen", 26, GenderType.F, "USA"),
        new Person("Thilini", 25, GenderType.F, "Sri Lanka"),
        new Person("Anna", 23, GenderType.F, "UK"),
        new Person("Chelsea", 35, GenderType.F, "UK"),
        new Person("Saman", 43, GenderType.M, "Sri Lanka"),
        new Person("Dan", 27, GenderType.M, "UK")
    };

    Dictionary<GenderType, Dictionary<string, List<Person>>> groups =
        people.GroupBy(p => p.Gender).ToDictionary(g => g.Key,
            g1 => g1.GroupBy(p => p.Country).ToDictionary(g2 => g2.Key, g2 => g2.ToList()));

    Console.ReadLine();
}

即。不是每个组都有单独的变量,而是使用单个字典,其中键值是性别,值也是字典,其中包含国家/地区代码作为键值。这样可以轻松快捷地查找您想要的性别和国家组合。