65.9K
CodeProject 正在变化。 阅读更多。
Home

如何使用 LINQ GroupBy

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2009年4月8日

CPOL

2分钟阅读

viewsIcon

68379

如何使用 LINQ GroupBy。

LINQ 中的 ‘GroupBy’ 功能非常强大且实用。 当你在 LINQ 中使用 ‘GroupBy’ 时,它内部会调用一个扩展方法,该方法返回一个 System.Collections.Generic.IEnumerable<(Of <(IGrouping<(Of <(TKey, TSource>)>)>)>) 序列。

GroupBy<(Of <(TSource, TKey>)>)(IEnumerable<(Of <(TSource>)>), Func<(Of <(TSource, TKey>)>)) 方法返回一个 IGrouping<(Of <(TKey, TElement>)>) 对象的集合,每个不同的键对应一个对象。 键代表 IGrouping<(Of <(TKey, TElement>)>) 中每个值共有的属性,可以使用 ForEach 循环访问该键。

为了理解 LINQ 中的 GroupBy,我们来看一个例子。琳达在一家小型私营公司的人力资源部门工作。 为了方便人力资源流程,她想要一个简单的控制台应用程序来获取一些快速结果。 她需要以下 Employees 的详细信息

  • 原始 Employees 列表
  • FirstName 的首字母分组的 Employees 列表
  • Year 分组的 employees 列表(他们出生的年份)
  • YearMonth 分组的 employees 列表(他们出生的年份和月份)
  • 具有相同 Year Birthdayemployees 总数
  • 性别比例

让我们逐一处理这些需求,看看如何使用 LINQ 中的 ‘GroupBy’ 轻松实现它们。 我们首先创建一个简单的 employees (List<Employees>) 列表,并向其中添加一些数据。

class Program 
{ 
    static void Main(string[] args) 
    { 
        List<Employee> empList = new List<Employee>(); 
        empList.Add(new Employee() { ID = 1,
            FName = "John", MName = "", LName = "Shields",
            DOB = DateTime.Parse("12/11/1971"), Sex = 'M' }); 
        empList.Add(new Employee() { ID = 2, FName = "Mary",
            MName = "Matthew", LName = "Jacobs", DOB = DateTime.Parse("01/17/1961"),
            Sex = 'F' }); 
        empList.Add(new Employee() { ID = 3, FName = "Amber", MName = "Carl",
            LName = "Agar", DOB = DateTime.Parse("12/23/1971"), Sex = 'M' }); 
        empList.Add(new Employee() { ID = 4, FName = "Kathy", MName = "",
            LName = "Berry", DOB = DateTime.Parse("11/15/1976"), Sex = 'F' }); 
        empList.Add(new Employee() { ID = 5, FName = "Lena", MName = "Ashco",
            LName = "Bilton", DOB = DateTime.Parse("05/11/1978"), Sex = 'F' }); 
        empList.Add(new Employee() { ID = 6, FName = "Susanne", MName = "",
            LName = "Buck", DOB = DateTime.Parse("03/7/1965"), Sex = 'F' }); 
        empList.Add(new Employee() { ID = 7, FName = "Jim", MName = "",
            LName = "Brown", DOB = DateTime.Parse("09/11/1972"), Sex = 'M' }); 
        empList.Add(new Employee() { ID = 8, FName = "Jane", MName = "G",
            LName = "Hooks", DOB = DateTime.Parse("12/11/1972"), Sex = 'F' }); 
        empList.Add(new Employee() { ID = 9, FName = "Robert", MName = "",
            LName = "", DOB = DateTime.Parse("06/28/1964"), Sex = 'M' }); 
        empList.Add(new Employee() { ID = 10, FName = "Cindy", MName = "Preston",
            LName = "Fox", DOB = DateTime.Parse("01/11/1978"), Sex = 'M' }); 

        // Printing the List 
        Console.WriteLine("\n{0,2} {1,7} {2,8} {3,8} {4,23} {5,3}", 
            "ID", "FName", "MName", "LName", "DOB", "Sex"); 
        empList.ForEach(delegate(Employee e) 
        { 
            Console.WriteLine("{0,2} {1,7} {2,8} {3,8} {4,23} {5,3}", 
                e.ID, e.FName, e.MName, e.LName, e.DOB, e.Sex); 
        }); 

        Console.ReadLine(); 
    } 

    class Employee 
    { 
        public int ID { get; set; } 
        public string FName { get; set; } 
        public string MName { get; set; } 
        public string LName { get; set; } 
        public DateTime DOB { get; set; } 
        public char Sex { get; set; } 
    }

1. 按 FirstName 的首字母分组的员工列表

要显示按 FirstName 的首字母分组的 employees 列表,请使用此查询。

// Group People by the First Letter of their FirstName 
var grpOrderedFirstLetter = empList.GroupBy(employees => 
new String(employees.FName[0], 1)).OrderBy(employees => employees.Key.ToString());; 

foreach (var employee in grpOrderedFirstLetter) 
{ 
    Console.WriteLine("\n'Employees having First Letter {0}':", employee.Key.ToString()); 
    foreach (var empl in employee) 
    { 
        Console.WriteLine(empl.FName); 
    } 
} 

Console.ReadLine();

2. 按出生年份分组的员工列表

为了根据员工出生的年份进行分组,请使用此查询。

// Group People by the Year in which they were born 
var grpOrderedYr = empList.GroupBy(
   employees => employees.DOB.Year).OrderBy(employees => employees.Key); 

foreach (var employee in grpOrderedYr) 
{ 
    Console.WriteLine("\nEmployees Born In the Year " + employee.Key); 
    foreach (var empl in employee) 
    { 
        Console.WriteLine("{0,2} {1,7}", empl.ID, empl.FName); 
    } 
} 
Console.ReadLine();

3. 按出生年份和月份分组的员工列表

为了根据年份然后月份对 employees 进行分组,请使用此查询。

// Group people by the Year and Month in which they were born 
var grpOrderedYrMon = empList.GroupBy(employees => 
new DateTime(employees.DOB.Year,
    employees.DOB.Month, 1)).OrderBy(employees => employees.Key); ; 

foreach (var employee in grpOrderedYrMon) 
{ 
    Console.WriteLine(
        "\nEmployees Born in Year {0} - Month {1} is/are :",
        employee.Key.Year, employee.Key.Month); 
    foreach (var empl in employee) 
    { 
        Console.WriteLine("{0}: {1}", empl.ID, empl.FName); 
    } 
} 
Console.ReadLine();

4. 每年出生的生日总数

要获取同年出生的 employees 总数,请使用此查询。

// Count people grouped by the Year in which they were born 
var grpCountYrMon = empList.GroupBy(employees => employees.DOB.Year) 
.Select(lst => new {Year = lst.Key, Count = lst.Count()} ); 

foreach (var employee in grpCountYrMon) 
{ 
    Console.WriteLine("\n{0} were born in {1}",employee.Count, employee.Year); 
} 
Console.ReadLine();

5. 性别比例

要查找公司中的性别比例,请使用此查询。

// Sex Ratio 
var ratioSex = empList.GroupBy(ra => ra.Sex) 
.Select( emp => new 
{ 
    Sex = emp.Key, 
        Ratio = (emp.Count() * 100) / empList.Count 
}); 

foreach (var ratio in ratioSex) 
{ 
    Console.WriteLine("\n{0} are {1}%", ratio.Sex, ratio.Ratio); 
} 
Console.ReadLine();

© . All rights reserved.