声明:本文为www.cnc6.cn原创,转载时请注明出处,谢谢!

本文作者文采欠佳,文字表达等方面不是很好,但实际的代码例子是非常实用的,请作参考。

一、先准备要使用的类:

1、Person类:

    class Person{public string Name { set; get; }public int Age { set; get; }public string Gender { set; get; }public override string ToString() => Name;}

2、准备要使用的List,用于分组(GroupBy):

        List<Person> personList = new List<Person>{new Person{Name = "P1", Age = 18, Gender = "Male"},new Person{Name = "P2", Age = 19, Gender = "Male",},new Person{Name = "P2", Age = 17,Gender = "Female",}};

二、第一种用法:

public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

官方释义:根据指定的键选择器函数对序列中的元素进行分组。

我们要分组的集合为source,集合内每个元素的类型为TSource,这里第一个参数keySelector的类型为Func<TSource, TKey>,用于将TSource元素按照由此委托返回的类型TKey进行分组,结果为一个已分好组的集合(集合中的集合)。

编写客户端试验代码如下:

        var groups = personList.GroupBy(p => p.Gender);foreach (var group in groups){Console.WriteLine(group.Key);foreach(var person in group){Console.WriteLine($"\t{person.Name},{person.Age}");}}

以上代码指定的KeySelector是Person类的Gender属性,因此,以上会按照Gender(性别)进行分组,我们使用两个嵌套的foreach循环将分组的内容打印到控制台。

因为groups返回的类型为IEnumerable<IGouping<TKey,TSource>>,因此以上返回的类型为IEnumerable<IGouping<string,Person>>。

IGouping<string,Person>是已经分组后的集合,内部集合元素为Person,且IGouping有一个Key属性,类型为string(指的是Gender属性类型),用于分组的标识。

输出结果如下:

其等价的LINQ语句为:

var groups = from p in personListgroup p by p.Gender;

以上的意思可以这样理解:从personList取出p,并对p进行分组,使用分组的依据(Key)为p.Gender,并将分组的结果存储到pGroup,并将分组的结果选择出来合并成一个集合。

三、第二种用法:

public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer);

官方释义:根据指定的键选择器函数对序列中的元素进行分组,并使用指定的比较器对键进行比较。

这种比第一种方法多了一个参数,那就是一个相等比较器,目的是为了当TKey为自定义的类时,GroupBy能根据TKey指定的类根据相等比较器进行分组,

因此,自定义类如何进行分组,GroupBy是不知道的,需要自己定义自己的相等比较器。

首先,将personList更改如下(下划线部分):

        List<Person> personList = new List<Person>{new Person{Name = "P1", Age = 18, Gender = "Male"},new Person{Name = "P1", Age = 19, Gender = "Male",},new Person{Name = "P3", Age = 17,Gender = "Female",}};

其次,增加一个相等比较器类,用于对Person进行分组:

    class PersonEqualityComparer : IEqualityComparer<Person>{public bool Equals(Person x, Person y) => x.Name == y.Name;public int GetHashCode(Person obj) => obj.Name.GetHashCode();}

其中定义了如何对一个Person相等性定义,只要实现IEqualityComparer<Person>即可,这里以Name作为Person类是否相同的依据。

最后,现在我们对Person类进行分组,编写客户端实验代码如下:

        var groups = personList.GroupBy(p => p, new PersonEqualityComparer());foreach (var group in groups){Console.WriteLine(group.Key.ToString());foreach(var person in group){Console.WriteLine($"\t{person.Age},{person.Gender}");}}

以上的分组依据是Person类,并运用了自己定义的Person类相同比较器,只要Name相同,就分为一组,

输出结果如下:

四、第三种用法:

public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector);

官方释义:根据指定的键选择器函数对序列中的元素进行分组,并且通过使用指定的函数对每个组中的元素进行投影。

这个比第一种用法多了一个elementSelector,第一种用法是对集合本身按照TKey分组,并将自己(TSource)添加到分组内,而当前的用法则可以选择自己想要添加到分组内的元素类型。

编写客户端实验代码如下:

        var groups = personList.GroupBy(p => p.Gender, p=>p.Name);foreach (var group in groups){Console.WriteLine(group.Key.ToString());foreach(var name in group){Console.WriteLine($"\t{name}");}}

以上代码是按照p.Gender进行分组,并将p.Name作为组内的元素。

输出结果如下:

其等价的LINQ语句为:

var groups = from p in personListgroup p.Name by p.Gender;

五、第四种用法:

public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector);

官方释义:根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。

这个跟之前的用法都不同,之前的用法都是将结果进行分组,并返回IGrouping<TKey,TSource>对象,而当前用法则是返回自己定义的类型(TResult),在返回自己定义类型之前,将会传入两个参数,一个是TKey,为分组时指定的对象,另外一个则是IEnumerable<TSource>,为分组后的内部对象集合。

编写客户端实验代码如下:

            string GetPersonInfo(string gender, IEnumerable<Person> persons){string result = $"{gender}:\t";foreach (var p in persons){result += $"{p.Name},{p.Age}\t";}return result;}var results = personList.GroupBy(p => p.Gender,(g, ps) => GetPersonInfo(g,ps));foreach (var result in results){Console.WriteLine(result);}

GetPersonInfo为局部方法,见于C#7.0及以上。

以上代码将分组后的内容(一个是TKey,为p.Gender,另外一个是IEnumerable<TSource>,为IEnumerable<Person>)作为字符串输出,因此,将返回的类型为字符串集合。

输出结果如下:

其等价的LINQ语句为:

            var results = from p in personListgroup p by p.Gender into pGroupselect GetPersonInfo(pGroup.Key, pGroup);

六、第五种用法:

public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer);

官方释义:根据键选择器函数对序列中的元素进行分组。通过使用比较器对键进行比较,并且通过使用指定的函数对每个组的元素进行投影。

与第三种用法基本相同,只是多了一个相等比较器,用于分组的依据。

使用第二种用法的personList及PersonEqualityComparer,编写客户端实验代码如下:

            var groups = personList.GroupBy(p => p, p => new { p.Age,p.Gender },new PersonEqualityComparer());foreach (var group in groups){Console.WriteLine(group.Key.ToString());foreach (var name in group){Console.WriteLine($"\t{name.Age},{name.Gender}");}}

以上代码的分组依据是Person,PersonEqualityComparer则是作为Person分组的比较器,每个组内为一个匿名类型集合。

输出结果如下:

七、第六种用法:

public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector, IEqualityComparer<TKey> comparer);

官方释义:根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。通过使用指定的比较器对键进行比较。

与第四种用法基本相同,只是多了一个相等比较器,用于分组的依据。

使用第二种用法的personList及PersonEqualityComparer,编写客户端实验代码如下:

            string GetPersonInfo(Person person, IEnumerable<Person> persons){string result = $"{person.ToString()}:\t";foreach (var p in persons){result += $"{p.Age},{p.Gender}\t";}return result;}var results = personList.GroupBy(p => p, (p, ps) => GetPersonInfo(p, ps),new PersonEqualityComparer());foreach (var result in results){Console.WriteLine(result);}

以上代码的分组依据是Person,PersonEqualityComparer则是作为Person分组的比较器,每个组内为一个Person集合,并将返回类型为string的字符串输出。

输出结果如下:

八、第七种用法:

public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector);

官方释义:根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。通过使用指定的函数对每个组的元素进行投影。

与第四种方法很类似,只是对分组内的元素进行选择,原有为TSource,现改为TElement。

编写客户端实验代码如下:

            string GetPersonInfo(string gender, IEnumerable<string> names){string result = $"{gender}:\t";foreach (var name in names){result += $"{name}\t";}return result;}var results = personList.GroupBy(p => p.Gender, (p=>p.Name) ,(g, ns) => GetPersonInfo(g, ns));foreach (var result in results){Console.WriteLine(result);}

以上代码将使用Gender分组,并将分组后的信息组合成一条字符串,并输出到控制台。

输出结果如下:

九、第八种用法:

public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector, IEqualityComparer<TKey> comparer);

官方释义: 根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。通过使用指定的比较器对键值进行比较,并且通过使用指定的函数对每个组的元素进行投影。

与第七种用法基本相同,只是多了一个相等比较器,用于分组的依据。

使用第二种用法的personList及PersonEqualityComparer,编写客户端实验代码如下:

            var results = personList.GroupBy(p => p, (p=>new { p.Age,p.Gender}),(p, ns) => {string result = $"{p.ToString()}:\t";foreach (var n in ns){result += $"{n.Age},{p.Gender}\t";}return result;},new PersonEqualityComparer());foreach (var result in results){Console.WriteLine(result);}

以上代码将使用Person分组,使用Person比较器作为分组的依据,并将分组后的信息组合成一条字符串,并输出到控制台。

输出结果如下:

转载于:https://www.cnblogs.com/cncc/p/9846390.html

[C#] LINQ之GroupBy相关推荐

  1. 转载Linq中GroupBy方法的使用总结

    Group在SQL经常使用,通常是对一个字段或者多个字段分组,求其总和,均值等. Linq中的Groupby方法也有这种功能.具体实现看代码: 假设有如下的一个数据集: public class St ...

  2. Linq之GroupBy用法

    1.简单形式: var q = from p in db.Products group p by p.CategoryID into g select g; 语句描述:Linq使用Group By按C ...

  3. linux没有mysql.server,[linux]centos7下解决yum install mysql-server没有可用包

    第一步:安装从网上下载文件的wget命令 [root@master ~]# yum -y install wget 第二步:下载mysql的repo源 [root@master ~]# wget ht ...

  4. atitit. groupby linq的实现(1)-----linq框架选型 java .net php

    atitit.  groupby linq的实现(1)-----linq框架选型 java .net php 实现方式有如下 1. Dsl/ Java8 Streams AP ,对象化的查询api , ...

  5. LINQ分组查询—GroupBy()

    今天写项目时遇到一个分组查询的需求:将订单列表中商品明细按商品编号汇总,我这里简单的mark一下. 之所以要记录,是因为之前很少用linq去写分组查询,其次是在此过程中遇到了一个小问题. 我们都知道l ...

  6. LINQ 学习路程 -- 查询操作 GroupBy ToLookUp

    Grouping Operators Description GroupBy GroupBy操作返回根据一些键值进行分组,每组代表IGrouping<TKey,TElement>对象 To ...

  7. LINQ根据某字段GroupBy

    2019独角兽企业重金招聘Python工程师标准>>> var DS = D_Report.Init.GetReportData(YPPH, ProceduresName).Tabl ...

  8. Linq(03)基础之Orderby group-by

    说明:本内容来自微软的MSDN,好记性不如烂笔头,加深印象. 我的心得:@开头 Let子句 1)      在查询表达式中,存储子表达式的结果有时很有用,这样可以在随后的子句中使用. 2)       ...

  9. Linq 中按照多个值进行分组(GroupBy)

    /// <summary>要查询的对象</summary> class Employee {public int ID { get;set; }public string FN ...

  10. 技术图文:如何通过 LINQ 查找集合中的重复数据?

    背景 在前几天介绍的 如何利用C#实现Huffman编码? 的图文中有以下代码. private List<HuffmanTreeNode> CreateInitForest(string ...

最新文章

  1. centos 7 部署k8s集群
  2. effective C++ 读书笔记(11-28)
  3. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](三)
  4. ajax头文件报错,AJAX的CSRF保护
  5. Python面向对象的三大特性
  6. VTK:Animation用法实战
  7. opensource项目_Opensource.com 3月预览
  8. 鼠标侧键能改为ctrl吗_200元档次又一高竞争力外设 雷柏V30鼠标评测
  9. Oracle用户密码过期策略
  10. 03-0006 Python批量查询手机归属地
  11. 大合集!2019-2020年目标跟踪资源全汇总(论文、模型代码、优秀实验室)
  12. windows、mac桌面录制GIF
  13. matlab扩充内存,matlab中内存不够用的解决方案
  14. 罗克韦尔自动化荣膺“2019全球最具商业道德企业”,这是该公司第11年上榜
  15. 面向对象程序设计C++学习之路2
  16. 在Home Assistant 添加MariaDB数据库
  17. 由前序序列与中序序列实现后序遍历
  18. HTC Desire (G7) VS MOTO Milestone VS MOTO XT800 个人对比评测
  19. WIN10没有按快捷键,突然弹出touchpad driver diagnostics
  20. 微信怎么建群?微信怎样建群拉人?微信建群拉人是这样做的…

热门文章

  1. python与mongodb更新_Python对MongoDB增删改查
  2. json 数据 生成 图表_比Excel更美观!你可知PhotoShop也能画图表
  3. C语言的全局变量和局部变量的作用域
  4. 将json字符串转换成html,根据json字符串生成Html的一种方式
  5. 二叉搜索树 最近共同祖先 c++_Task 14. 树:236. 二叉树的最近公共祖先
  6. u8显示云服务器已离线_u8登录不知道这样的主机
  7. matlab程序中中零内插在qdpsk调制中的作用,桂林电子科技大学通信原理思考题
  8. 地图画指定区域_善用GIS 妙绘“环卫”一图画卷
  9. 说明assert()的作用:assert()是一个调试程序时经常使用的宏,在程序执行时计算括号内的表达式,如果表达式为假,程序报告错误,并终止执行;若表达式为真,则继续执行后面的语句。
  10. 相干检测--概念,原理,科斯塔斯环