如何使用 LINQ GroupBy
如何使用 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
列表(他们出生的年份) - 按
Year
和Month
分组的employees
列表(他们出生的年份和月份) - 具有相同
Year
Birthday
的employees
总数 - 性别比例
让我们逐一处理这些需求,看看如何使用 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();