介绍
GroupBy
是 C# 中的一个 LINQ 扩展方法,用于根据指定的键将序列中的元素分组。它可以根据提供的键函数将数据分割成多个组,每组包含具有相同键的元素。
GroupBy
也是一个在集合用比较常用的方法,也是比较好用的,适用于对序列中的元素进行分组,他有多种重载,可以实现不同的功能,具体定义如下:
他有多种重载,具体定义如下:
定义 | 说明 |
---|---|
GroupBy<TSource,TKey,TElement,TResult>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, Func<TKey,IEnumerable<TElement>,TResult>) | 根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的函数对每个组的元素进行投影。 |
GroupBy<TSource,TKey,TElement,TResult>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource,TElement>, Func<TKey,IEnumerable<TElement>, TResult>, IEqualityComparer<TKey>) | 根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的比较器对键值进行比较,并且通过使用指定的函数对每个组的元素进行投影。 |
GroupBy<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>) | 根据指定的键选择器函数对序列中的元素进行分组,并且通过使用指定的函数对每个组中的元素进行投影。 |
GroupBy<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, IEqualityComparer<TKey>) | 根据键选择器函数对序列中的元素进行分组。 通过使用比较器对键进行比较,并且通过使用指定的函数对每个组的元素进行投影。 |
GroupBy<TSource,TKey,TResult>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TKey,IEnumerable<TSource>,TResult>) | 根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 |
GroupBy<TSource,TKey,TResult>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TKey,IEnumerable<TSource>,TResult>, IEqualityComparer<TKey>) | 根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的比较器对键进行比较。 |
GroupBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>) | 根据指定的键选择器函数对序列中的元素进行分组。 |
GroupBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>) | 根据指定的键选择器函数对序列中的元素进行分组,并使用指定的比较器对键进行比较。 |
使用
测试数据
定义 一个Device
类,包括设备ID,名称,类型和测试结果,然后初始化添加4条数据
/// <summary>
/// 设备类
/// </summary>
class Device
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 设备类型
/// </summary>
public string Type { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 测试结果
/// </summary>
public int Result { get; set; }
}
//初始化数据
List<Device> list = new List<Device>();
list.Add(new Device() { Id = 101, Name = "1号设备", Type = "生产设备", Result = 99 });
list.Add(new Device() { Id = 102, Name = "2号设备", Type = "生产设备", Result = 60 });
list.Add(new Device() { Id = 103, Name = "3号设备", Type = "测试设备", Result = 98 });
list.Add(new Device() { Id = 104, Name = "4号设备", Type = "测试设备", Result = 70 });
list.Add(new Device() { Id = 201, Name = "5号生产设备", Type = "生产设备", Result = 100 });
list.Add(new Device() { Id = 202, Name = "6号测试设备", Type = "测试设备", Result = 89 });
list.Add(new Device() { Id = 203, Name = "7号测试设备", Type = "测试设备", Result = 98 });
list.Add(new Device() { Id = 204, Name = "8号测试设备", Type = "测试设备", Result = 95 });
分组用法
根据某一属性的值进行分组
示例:
根据设备的类型进行分组
var groups = list.GroupBy(x => x.Type);
foreach (var group in groups)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine(
$"ID:{item.Id},Name:{item.Name},Type:{item.Type},Result:{item.Result}"
);
}
}
根据判断条件进行分组
这个最终分组是True和False两个组
示例:
以测试结果大于90为合格,分成合格和不合格两个组
var groups2 = list.GroupBy(x => x.Result > 90);
foreach (var group in groups2)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine(
$"ID:{item.Id},Name:{item.Name},Type:{item.Type},Result:{item.Result}"
);
}
}
结果:
分组数据处理
可以用GroupBy直接处理分组数据,并转换成新的类
示例
获取组的数量,最大值,最小值等等
var group3 = list.GroupBy(
item => item.Result / 10,
pet => pet.Result,
(baseResult, results) =>
new
{
Key = baseResult,
Count = results.Count(),
Min = results.Min(),
Max = results.Max(),
}
);
foreach (var group in group3)
{
Console.WriteLine($"Group:{group.Key * 10}--{group.Key * 10 + 9}");
Console.WriteLine($"Count:{group.Count}");
Console.WriteLine($"Min:{group.Min}");
Console.WriteLine($"Max:{group.Max}");
Console.WriteLine();
}