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

Group在SQL经常使用,通常是对一个字段或者多个字段分组,求其总和,均值等。

Linq中的Groupby方法也有这种功能。具体实现看代码:

假设有如下的一个数据集:

  1. public class StudentScore 
  2.     { 
  3.         public int ID { setget; } 
  4.         public string Name { setget; } 
  5.         public string Course { setget; } 
  6.         public int Score { setget; } 
  7.         public string Term { setget; } 
  8.     } 
  9. List<StudentScore> lst = new List<StudentScore>() { 
  10.                 new StudentScore(){ID=1,Name="张三",Term="第一学期",Course="Math",Score=80}, 
  11.                 new StudentScore(){ID=1,Name="张三",Term="第一学期",Course="Chinese",Score=90}, 
  12.                 new StudentScore(){ID=1,Name="张三",Term="第一学期",Course="English",Score=70}, 
  13.                 new StudentScore(){ID=2,Name="李四",Term="第一学期",Course="Math",Score=60}, 
  14.                 new StudentScore(){ID=2,Name="李四",Term="第一学期",Course="Chinese",Score=70}, 
  15.                 new StudentScore(){ID=2,Name="李四",Term="第一学期",Course="English",Score=30}, 
  16.                 new StudentScore(){ID=3,Name="王五",Term="第一学期",Course="Math",Score=100}, 
  17.                 new StudentScore(){ID=3,Name="王五",Term="第一学期",Course="Chinese",Score=80}, 
  18.                 new StudentScore(){ID=3,Name="王五",Term="第一学期",Course="English",Score=80}, 
  19.                 new StudentScore(){ID=4,Name="赵六",Term="第一学期",Course="Math",Score=90}, 
  20.                 new StudentScore(){ID=4,Name="赵六",Term="第一学期",Course="Chinese",Score=80}, 
  21.                 new StudentScore(){ID=4,Name="赵六",Term="第一学期",Course="English",Score=70}, 
  22.                 new StudentScore(){ID=1,Name="张三",Term="第二学期",Course="Math",Score=100}, 
  23.                 new StudentScore(){ID=1,Name="张三",Term="第二学期",Course="Chinese",Score=80}, 
  24.                 new StudentScore(){ID=1,Name="张三",Term="第二学期",Course="English",Score=70}, 
  25.                 new StudentScore(){ID=2,Name="李四",Term="第二学期",Course="Math",Score=90}, 
  26.                 new StudentScore(){ID=2,Name="李四",Term="第二学期",Course="Chinese",Score=50}, 
  27.                 new StudentScore(){ID=2,Name="李四",Term="第二学期",Course="English",Score=80}, 
  28.                 new StudentScore(){ID=3,Name="王五",Term="第二学期",Course="Math",Score=90}, 
  29.                 new StudentScore(){ID=3,Name="王五",Term="第二学期",Course="Chinese",Score=70}, 
  30.                 new StudentScore(){ID=3,Name="王五",Term="第二学期",Course="English",Score=80}, 
  31.                 new StudentScore(){ID=4,Name="赵六",Term="第二学期",Course="Math",Score=70}, 
  32.                 new StudentScore(){ID=4,Name="赵六",Term="第二学期",Course="Chinese",Score=60}, 
  33.                 new StudentScore(){ID=4,Name="赵六",Term="第二学期",Course="English",Score=70}, 
  34.             }; 

可以把这个数据集想象成数据库中的一个二维表格。

示例一

通常我们会把分组后得到的数据放到匿名对象中,因为分组后的数据的列不一定和原始二维表格的一致。当然要按照原有数据的格式存放也是可以的,只需select的时候采用相应的类型即可。

第一种写法很简单,只是根据下面分组。 

  1. //分组,根据姓名,统计Sum的分数,统计结果放在匿名对象中。两种写法。 
  2. //第一种写法 
  3. Console.WriteLine("---------第一种写法"); 
  4. var studentSumScore_1 = (from l in lst 
  5.                          group l by l.Name into grouped 
  6.                          orderby grouped.Sum(m => m.Score) 
  7.                          select new { Name = grouped.Key, Scores = grouped.Sum(m => m.Score) }).ToList(); 
  8. foreach (var l in studentSumScore_1) 
  9.     Console.WriteLine("{0}:总分{1}", l.Name, l.Scores); 
  10. 第二种写法和第一种其实是等价的。 
  11. //第二种写法 
  12. Console.WriteLine("---------第二种写法"); 
  13. var studentSumScore_2 = lst.GroupBy(m => m.Name) 
  14.     .Select(k => new { Name = k.Key, Scores = k.Sum(l => l.Score) }) 
  15.     .OrderBy(m => m.Scores).ToList(); 
  16. foreach (var l in studentSumScore_2) 
  17.     Console.WriteLine("{0}:总分{1}", l.Name, l.Scores); 

 

示例二

当分组的字段是多个的时候,通常把这多个字段合并成一个匿名对象,然后group by这个匿名对象。

注意:groupby后将数据放到grouped这个变量中,grouped 其实是IGrouping<TKey, TElement>类型的,IGrouping<out TKey, out TElement>继承了IEnumerable<TElement>,并且多了一个属性就是Key,这个Key就是当初分组的关键字,即那些值都相同的字段,此处就是该匿名对象。可以在后续的代码中取得这个Key,便于我们编程。

orderby多个字段的时候,在SQL中是用逗号分割多个字段,在Linq中就直接多写几个orderby。

  1. //分组,根据2个条件学期和课程,统计各科均分,统计结果放在匿名对象中。两种写法。 
  2. Console.WriteLine("---------第一种写法"); 
  3. var TermAvgScore_1 = (from l in lst 
  4.                       group l by new { Term = l.Term, Course = l.Course } into grouped 
  5.                       orderby grouped.Average(m => m.Score) ascending 
  6.                       orderby grouped.Key.Term descending 
  7.                       select new { Term = grouped.Key.Term, Course = grouped.Key.Course, Scores = grouped.Average(m => m.Score) }).ToList(); 
  8. foreach (var l in TermAvgScore_1) 
  9.     Console.WriteLine("学期:{0},课程{1},均分{2}", l.Term, l.Course, l.Scores); 
  10. Console.WriteLine("---------第二种写法"); 
  11. var TermAvgScore_2 = lst.GroupBy(m => new { Term = m.Term, Course = m.Course }) 
  12.     .Select(k => new { Term = k.Key.Term, Course = k.Key.Course, Scores = k.Average(m => m.Score) }) 
  13.     .OrderBy(l => l.Scores).OrderByDescending(l => l.Term); 
  14. foreach (var l in TermAvgScore_2) 
  15.     Console.WriteLine("学期:{0},课程{1},均分{2}", l.Term, l.Course, l.Scores); 

示例三

Linq中没有SQL中的Having语句,因此是采用where语句对Group后的结果过滤。 

  1. //分组,带有Having的查询,查询均分>80的学生 
  2. Console.WriteLine("---------第一种写法"); 
  3. var AvgScoreGreater80_1 = (from l in lst 
  4.                   group l by new { Name = l.Name, Term = l.Term } into grouped 
  5.                   where grouped.Average(m => m.Score)>=80 
  6.                   orderby grouped.Average(m => m.Score) descending 
  7.                   select new { Name = grouped.Key.Name, Term = grouped.Key.Term, Scores = grouped.Average(m => m.Score) }).ToList(); 
  8. foreach (var l in AvgScoreGreater80_1) 
  9.     Console.WriteLine("姓名:{0},学期{1},均分{2}", l.Name, l.Term, l.Scores); 
  10. Console.WriteLine("---------第二种写法"); 
  11. //此写法看起来较为复杂,第一个Groupby,由于是要对多个字段分组的,因此构建一个匿名对象,
  12. 对这个匿名对象分组,分组得到的其实是一个IEnumberable<IGrouping<匿名类型,StudentScore>>这样一个类型。
  13. Where方法接受,和返回的都同样是IEnumberable<IGrouping<匿名类型,StudentScore>>类型,
  14. 其中Where方法签名Func委托的类型也就成了Func<IGrouping<匿名类型,StudentScore>,bool>,
  15. 之前说到,IGrouping<out TKey, out TElement>继承了IEnumerable<TElement>,
  16. 因此这种类型可以有Average,Sum等方法。 
  17. var AvgScoreGreater80_2 = lst.GroupBy(l => new { Name = l.Name, Term = l.Term }) 
  18.     .Where(m => m.Average(x => x.Score) >= 80) 
  19.     .OrderByDescending(l=>l.Average(x=>x.Score)) 
  20.     .Select(l => new { Name = l.Key.Name, Term = l.Key.Term, Scores = l.Average(m => m.Score) }).ToList(); 
  21. foreach (var l in AvgScoreGreater80_2) 
  22.     Console.WriteLine("姓名:{0},学期{1},均分{2}", l.Name, l.Term, l.Scores); 
  23. }  

 

转载于:https://www.cnblogs.com/wphl-27/p/3480167.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460644.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Atom中运行脚本

2019独角兽企业重金招聘Python工程师标准>>> 现在可以在atom官网&#xff08;https://atom.io/&#xff09;找到deb包。 插件script可以让atom运行脚本&#xff0c;具体请见&#xff1a;https://atom.io/packages/script。 下面大致讲一下如何使用。 安装atom后&…

js中的this

在面向对象编程语言中&#xff0c;对于this关键字我们是非常熟悉的。比如C、C#和Java等都提供了这个关键字&#xff0c;虽然在开始学习的时候觉得比较难&#xff0c;但只要理解了&#xff0c;用起来是非常方便和意义确定的。JavaScript也提供了这个this关键字&#xff0c;不过用…

在 Windows Azure 上部署并定制化 FreeBSD 虚拟机镜像

&#xfeff;&#xfeff;发布于 2014-12-11作者 陈阳FreeBSD 基础镜像现已登陆中国的 VM Depot&#xff01; 对于青睐 BSD 而非 Linux 的开源爱好者来说&#xff0c;这无疑是个好消息。同时&#xff0c;随着该基础镜像的可用&#xff0c;我们期待很快看到更多来自社区的基于 F…

如何理解套接字的形容词前缀:“面向连接”与“无连接”

以下内容源于C语言中文网资料的学习与整理&#xff0c;非本人原创&#xff0c;如有侵权请告知删除。 前言 在《网络套接字socket的简介》一文中提到&#xff0c;流格式套接字&#xff08;Stream Sockets&#xff09;就是“面向连接的套接字”&#xff0c;它基于 TCP 协议&…

文件IO——Linux系统如何管理文件

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 硬盘中的静态文件 文件平时以一种固定的形式存放在硬盘中&#xff0c;我们叫它静态文件。 一块硬盘中可以分为两大区域&#xff1a;一个是硬盘内容管理表&#xff0c;另一个是真正存储内容的区域。 …

java String类 常用函数

为什么80%的码农都做不了架构师&#xff1f;>>> 1. 获取 int indexOf(int c) int indexOf(int c, int start) char charAt(int index) 2.判断 判断是否包含一个字符串 boolean contains(CharSequence cs) indexOf() //也可以用来判断是否包含 判断是否有内容 boole…

设备驱动程序的简介

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、驱动的概念 设备驱动程序&#xff08;Device Driver&#xff09;&#xff0c;简称驱动程序、驱动&#xff08;Driver&#xff09;&#xff0c;指操作系统中用来操控硬件的代码。 驱动是硬件与操…

Android开发实践:掌握Camera的预览方向和拍照方向

Android的Camera相关应用开发中&#xff0c;有一个必须搞清楚的知识点&#xff0c;就是Camera的预览方向和拍照方向&#xff0c;本文就重点讨论一下这个问题。图像的Sensor方向&#xff1a;手机Camera的图像数据都是来自于摄像头硬件的图像传感器&#xff08;Image Sensor&…

SecureCRT显示乱码的解决办法

发现问题 在Ubuntu中编写代码&#xff0c;输出语句里带有中文&#xff0c;比如"printf("读出来的内容是&#xff1a;%s.\n", buf);"。使用交叉编译工具链编译后&#xff0c;将可执行程序转移至开发板系统运行&#xff0c;并使用SCRT来观测测试结果。此时发…

WCF数据契约

当使用DataMember时&#xff0c;和访问符无关&#xff0c;及时使用了private&#xff0c;成员都是可见的。相反如果使用static&#xff0c;为不可见。 上述的两个数据成员是等效的&#xff0c;如果是等效的话 数据成员的顺序也必须是相同的。 4.数据契约已知类型——使用KownTy…

spring mvc 配置解析之xml

2019独角兽企业重金招聘Python工程师标准>>> ##mvc.xml中可配置的元素## 既然是xml,当然是要遵循schema的规定. 那么schema文件在哪呢? 定位方法就是解开这个jar文件,找到META-INF/spring.schema文件,这是个文本文件,里面包含了namespace以及其对应的xsd文件的位置…

JDBC学习笔记——事务、存储过程以及批量处理

2019独角兽企业重金招聘Python工程师标准>>> 1、事务 1.1、事务的基本概念和使用示例 数据库事务&#xff0c;是指作为单个逻辑工作单元执行的一系列操作&#xff0c;要么完整…

验证码识别笔记(二)

这是验证码识别的第二篇&#xff0c;先看一下样图吧&#xff0c;就是下面那张。 看到这张图片&#xff0c;直观上就知道比第一篇中的要简单&#xff0c;这个“简单”用语言来描述&#xff0c;可以得到下面的几条结论&#xff1a; 1. 图片中的字符边界比较清晰&#xff0c;并且单…

centos6.5下搭建oracle 11g

为什么80%的码农都做不了架构师&#xff1f;>>> 安装依赖 yum install binutils compat-libstdc-33 compat-libstdc-33.i686 \ elfutils-libelf elfutils-libelf-devel gcc gcc-c glibc glibc.i686 \ glibc-common glibc-devel glibc-devel.i686 glibc-headers ksh…

JS 学习笔记--11---内置对象(Global/Math)

练习中使用的浏览器是IE10&#xff0c;如果各位朋友有不同意见或者遇到浏览器不兼容问题&#xff0c;希望指正 1、内置对象的定义&#xff1a;有ECMAScript实现提供的、不依赖与宿主环境的对象&#xff0c;在ECMAScript运行之前就已经创建好的对象就叫做内置对象。就是说&…

SQL Server 视图设计器

SQL Server 中经常需要写一些查询&#xff0c;关联好多张表&#xff0c;显示无数个列。如果使用视图设计器&#xff0c;可以大大提高效率&#xff0c;同是减少差错。1. 启动视图设计器为数据库“新建视图”&#xff0c;将启用视图设计器。2. 添加表在起始界面&#xff0c;将出现…

misc类设备驱动1——板载蜂鸣器驱动测试

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、驱动部分 1、前言 九鼎移植的内核已经提供了蜂鸣器驱动源码&#xff08;在SI中搜索关键字buzzer&#xff0c;发现出现有x210-buzzer.c文件&#xff1b;或者在make menuconfig界面搜索buzzer&am…

github和git@osc提交问题

为什么80%的码农都做不了架构师&#xff1f;>>> 今天想用gitosc push下测试下自己能否正常使用gitosc的git仓库的&#xff0c;公钥SSH 已经加好。 ssh -T gitgit.oschina.net 测试正常。 结果报错could not read Username for https://git.oschina.net: No such fi…

怎样跟踪来访用户?

某些监视方法是比较容易想到的&#xff0c;比如&#xff0c;当你登录网站的时候&#xff0c;它就可以知道你是谁了。但是这些网络监视系统是如何通过你的上网行为记录你的个人信息呢&#xff1f; 广告系统经常通过追踪用户行为的方法来建立用户信息库&#xff0c;以定位谁是目标…

【百度地图API】如何制作班级地理通讯录?LBS通讯录

原文:【百度地图API】如何制作班级地理通讯录&#xff1f;LBS通讯录摘要&#xff1a;班级通讯录必备的功能&#xff0c;比如人员列表&#xff0c;人员地理位置标注&#xff0c;展示复杂信息窗口&#xff0c;公交和驾车等。一般班级人员都不会超过300个&#xff0c;因为可以高效…