转载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,一经查实,立即删除!

相关文章

例程:Linux下的socket演示程序1

server.cpp 是服务器端代码&#xff0c;client.cpp 是客户端代码。 要实现的功能是&#xff1a;客户端从服务器读取一个字符串并打印出来。 服务器端代码 server.cpp&#xff1a; #include <stdio.h> #include <string.h> #include <stdlib.h> #include &…

在Atom中运行脚本

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

例程:socket编程实现文件传输功能

程序要实现的功能&#xff1a;client 从 server 下载一个文件并保存到本地。 编写这个程序需要注意两个问题&#xff1a; &#xff08;1&#xff09;文件大小不确定 有可能比缓冲区大很多&#xff0c;调用一次 write()/send() 函数不能完成文件内容的发送。接收数据时也会遇…

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…

man命令:查找linux命令、API或者C库函数

可以使用man命令。 man 1 xxx 1表示查找linux命令&#xff0c;比如 man 1 ls man 2 xxx 2表示查找linux API &#xff0c;比如 man 2 socket man 3 xxx 3表示查找C库函数&#xff0c;比如 man 3 print

关于在asp.net中播放MP4格式的视频(好吧,只兼容支持html5的浏览器,ie8及以下的都歇菜了)...

项目要求只能播放MP4格式的视频&#xff0c;同事的播放器在我这里不完全管用&#xff0c;对于部分mp4格式的视频编码不支持&#xff0c;所以各种在网上找&#xff0c;在http://www.iteye.com/problems/75503问答的一个网友答案中找到了适合项目中当前mp4格式的播放器&#xff0…

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

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

1682: [Usaco2005 Mar]Out of Hay 干草危机

1682: [Usaco2005 Mar]Out of Hay 干草危机 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 391 Solved: 258[Submit][Status]Description The cows have run out of hay, a horrible event that must be remedied immediately. Bessie intends to visit the other farms to …

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

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

oracle存储过程 --1

一&#xff0c;oracle存储过程语法 1.oracle存储过程结构 CREATE OR REPLACE PROCEDURE oracle存储过程名字 ( 参数1 IN NUMBER, 参数2 IN NUMBER ) IS 变量1 INTEGER :0; 变量2 DATE; BEGIN END oracle存储过程名字 2.无返回值的oracle存储过程 create or replac…

RHEL/CentOS下编译安装Nginx

##下载nginx源码&#xff1a;wget http://nginx.org/download/nginx-1.7.8.tar.gz tar -xv -f nginx-1.7.8.tar.gz -C /usr/local/src/##安装编译环境和必须的组件&#xff1a;yum groupinstall Development Tools yum install pcre pcre-devel zlib zlib-devel openssl openss…

12.13记录//QQDemo示例程序源代码

笔记的完整版pdf文档下载地址: https://www.evernote.com/shard/s227/sh/ac692160-68c7-4149-83ea-0db5385e28b0/5742995e6034e3d3f5c4793465d50a8c 笔记的文本摘要如下所示: 注意:以下仅仅是文本摘要,没有贴图,出现右边的图标()表示笔记中此处有图片,完整笔记请前往pdf链接中观…

文件IO——文件IO的API

以下内容源于网络资源的学习与整理&#xff0c;如有侵权&#xff0c;请告知删除。 文件操作的一般步骤 在Linux系统中要操作一个文件&#xff0c;一般是先使用open函数打开文件&#xff0c;得到一个文件描述符&#xff0c;然后对文件进行读写操作&#xff08;或其他操作&#x…

【转】功能测试的经验总结

测试准备&#xff1a; 1、实际测试总比你预想的要花更多的时间&#xff0c;遇到更多的麻烦&#xff0c;所以要尽量争取足够的测试时间&#xff0c;不要不加思索的说这个东西我一星期肯定可以测完。还要尽可能考虑到测试过程中的风险&#xff0c;比如测试环境的问题、部署失败的…

文件IO——open函数的参数flags详解

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 前言 在命令行中使用“man 2 open”可以获知open这个文件IO API的使用方法。 open函数的模型有两种&#xff0c;根据需要选择其中一种即可。 int open(const char *pathname, int flags); int open(…

oracle建库及plsql建表空间的用法

所有程序—》ORACLE-JHEMR-----------》配置和移植工具-----》DataBase Configuration Assistant-------中间就需要改一个数据仓库即可&#xff0c;其他的都是下一步&#xff0c;统一口令为**然后建监听服务&#xff0c;测试时改登录为system **&#xff0c;之后用plsql登录上&…

USACO 1.5.4 Checker Challenge

题意&#xff1a;经典的八皇后问题 解法&#xff1a; 采用朴素的每一次放置都与前面的所有行进行比较&#xff0c;在N 13的时候时间会爆掉 《入门经典》上提供的方法很经典&#xff0c;vis数组的使用&#xff0c;具体见《入门经典》125页 /* ID:lsswxr1 PROG:checker LANG:C */…

Spark 1.1.1 Submitting Applications

回到目录 Submitting Applications The spark-submit script in Spark’s bin directory is used to launch applications on a cluster. It can use all of Spark’s supported cluster managersthrough a uniform interface so you don’t have to configure your applicatio…

如何描述变量:存储类、生命周期,作用域、链接属性

可以根据一个变量的存储类、作用域、链接属性、生命周期来描述该变量。 其中&#xff0c;存储类决定了生命周期&#xff0c;作用域决定了链接属性。 存储类 存储类表明变量在哪里存储。见博文Linux下C语言程序的内存布局_天糊土的博客-CSDN博客 作用域 作用域表明变量起作用的…