LINQ常用扩展方法、委托、Lambda、yield

LINQ让数据处理变得简单

文章目录

    • Where方法
    • Count()方法
    • Any()方法
    • 获取一条数据(是否带参数的两种写法)
      • Single
      • SingleOrDefault
      • First
      • FirstOrDefault
    • 排序
      • 多规则排序
    • 限制结果集,获取部分数据
    • 聚合函数
    • 分组
    • 投影
    • 匿名类型
    • 集合转换
    • 查询语法
    • 委托
      • Lambda表达式
      • LINQ
      • yield return

Where方法

 每一项数据都会经过predicate的测试,如果针对一个元素,predicate执行的返回值为true,那么这个元素就会放到返回值中。
Where参数是一个lambda表达式格式的匿名方法,方法的参数e表示当前判断的元素对象。参数的名字不一定非要叫e,不过一般lambda表达式中的变量名长度都不长。

 static void Main(string[] args){List<Employee> list = new List<Employee>();list.Add(new Employee { Id = 1, Name = "张三", Age = 30, Gender = false, Salary = 3500});list.Add(new Employee { Id = 2, Name = "李四", Age = 48, Gender = false, Salary = 6000});list.Add(new Employee { Id = 3, Name = "王五", Age = 16, Gender = true, Salary = 2800});list.Add(new Employee { Id = 4, Name = "赵六", Age = 16, Gender = false, Salary = 4100});list.Add(new Employee { Id = 5, Name = "田七", Age = 33, Gender = true, Salary = 3000});IEnumerable<Employee> items = list.Where(e => e.Age > 40);foreach (var item in items){Console.WriteLine(item);}}class Employee{public long Id { get; set; }public string Name { get; set; }//姓名public int Age { get; set; }//年龄public bool Gender { get; set; }//性别public int Salary { get; set; }//月薪public override string ToString(){return $"Id={Id},Name={Name},Age={Age},Gender={Gender},Salary={Salary}";}}

Count()方法

获取数据条数

int count1 = list.Count(e => e.Salary > 5000 || e.Age < 30);
int count2 = list.Where(e => e.Salary > 5000 || e.Age < 30).Count();

Any()方法

是否至少有一条数据

bool b1 = list.Any(e => e.Salary > 8000);
bool b2 = list.Where(e => e.Salary > 8000).Any();

比Count()实现效率高。

获取一条数据(是否带参数的两种写法)

Single

有且只有一条满足要求的数据,如果都不满足或者满足多条数据则抛出异常。

Employee e1= list.Where(e => e.Id == 4).Single();
Employee e2= list.Single(e => e.Id == 4);
Console.WriteLine(e2);

SingleOrDefault

最多只有一条满足要求的数据,如果都不满足返回默认值,如果满足多条则抛出异常。

Employee e2 = list.SingleOrDefault(e => e.Id == 4);
Employee e3 = list.SingleOrDefault(e => e.Id == 10);
Console.WriteLine(e3 == null);

First

至少有一条,返回第一条,如果都不满足抛出异常

Employee e4 = list.First(e => e.Age > 30);
Employee e5 = list.First(e => e.Age > 100);

FirstOrDefault

返回第一条或者默认值

Employee e6 = list.FirstOrDefault(e => e.Age > 100);
Console.WriteLine(e6 == null);

排序

Order() 对数据正序排序;

list.OrderBy(e => e.Age);

OrderByDescending() 倒序排序;

IEnumerable<Employee>  list2= list.OrderByDescending(e => e.Age);

用Guid或者随机数进行随机排序:

IEnumerable<Employee>  list2= list.OrderBy(e => Guid.NewGuid());Random random = new Random(); 
IEnumerable<Employee>  list2= list.OrderBy(e => random.Next());

按照最后一个字符排序:

IEnumerable<Employee>  list2= list.OrderBy(e => e.Name[e.Name.Length - 1]);

多规则排序

可以在Order()OrderByDescending()后继续写ThenBy ()ThenByDescending()
优先按照Age排序,如果Age相同再按照Salary排序

list.OrderBy(e => e.Age).ThenByDescending(e => e.Salary)
// 千万不要写成
// list.OrderBy(e => e.Age).OrderByDescending(e => e.Salary)

限制结果集,获取部分数据

Skip(n)跳过n条数据,Take(n)获取n条数据。
获取从第2条开始获取3条数据:

var orderedItems1 = list.Skip(2).Take(3);

Skip()Take()也可以单独使用。

var orderedItems1 = list.Skip(2);
var orderedItems2 = list.Take(3);

Tips:LINQ中所有的扩展方法几乎都是针对IEnumerable接口的,而几乎所有能返回集合的都返回IEnumerable,所以是可以把几乎所有方法“ 链式使用 ”的。

聚合函数

Max()Min()Average()Sum()Count()

//最大年龄
int a = list.Max(e => e.Age);
//最小年龄
int a = list.Min(e => e.Age);//年龄大于等于30岁的平均年龄
double b = list.Where(e => e.Age >= 30).Average(e => e.Age);//集合中所有年龄的和
int sum = list.Sum(e => e.Age);
//集合个数
int count = list.Count();

分组

GroupBy()方法参数是分组条件表达式,返回值为IGrouping<TKey, TSource>类型的泛型IEnumerable,也就是每一组以一个IGrouping对象的形式返回。IGrouping是一个继承自IEnumerable的接口,IGroupingKey属性表示这一组的分组数据的值。

IEnumerable<IGrouping<int, Employee>> g = list.GroupBy(x => x.Age);
foreach (IGrouping<int, Employee> item in g)
{Console.WriteLine(item.Key);foreach (var e in item){Console.WriteLine(e);}} 

投影

 投影是把集合中的每一项转换为另外一种类型。

IEnumerable<int> ages = list.Select(e => e.Age);
IEnumerable<string> names = list.Select(e=>e.Gender?"男":"女");
var dogs = list.Select(p=>new Dog{NickName=e.Name,Age=e.Age});

匿名类型

var p = new {Name="tom", Id=1};
//属性名称一样时,可以省略
var p1 = new {name, Id=1, p.Age};
var select = list.Select(e => new { NianLing = e.Age, XingBie = e.Gender ? "男" : "女" });
foreach (var item in select)
{Console.WriteLine(item.NianLing + "," + item.XingBie);
}      
var items = list.GroupBy(e => e.Gender).Select(g=>new { Gender=g.Key,Count=g.Count(),AvgSalary= g.Average(e => e.Salary),MinAge= g.Min(e => e.Age)});

通过反编译软件查看dll文件,编译器最后也是生成了具体的类,只不过这个类名是编译器自动生成的。

集合转换

 有一些地方需要数组类型或者List类型的变量,可以用ToArray()方法和ToList()分别把IEnumerable<T>转换为数组类型和List<T>类型。

查询语法

 使用Where、OrderBy、Select等 扩展方法进行数据查询的写法叫做 “LINQ方法语法”。还有一种“查询语法”的写法。

var items2 = from e in listwhere e.Salary > 3000orderby e.Ageselect new { e.Name, e.Age, Gender = e.Gender ? "男" : "女" };
//等同于以下写法
var items3 = list.Where(e => e.Salary > 3000).OrderBy(e => e.Age).Select(e => new { e.Name, e.Age, Gender = e.Gender ? "男" : "女" });

Tips:日常开发推荐方法语法

统计一个字符串中每个字母出现的频率(忽略大小写),然后按照从高到低的顺序输出出现频率高于2次的单词和其出现的频率:

var items = s.Where(c => char.IsLetter(c))//过滤非字母.Select(c => char.ToLower(c))//大写字母转换为小写.GroupBy(c => c)//根据字母进行分组.Where(g=>g.Count()>2)//过滤掉出现次数<=2.OrderByDescending(g => g.Count())//按次数排序.Select(g=>new { Char=g.Key,Count=g.Count()});

委托

1、委托是可以指向方法的类型,调用委托变量时执行的就是变量指向的方法。

static void Main(string[] args)
{D1 d = F1;d();
}
static void F1()
{Console.WriteLine("hello");
}
delegate void D1();

匿名方法

static void Main(string[] args)
{Action a = delegate() {Console.WriteLine("hello world");};a();
}
static void Main(string[] args)
{Action a = delegate() {Console.WriteLine("hello world");};Func<int, int, int> func = delegate (int a, int b){return a + b;};Console.WriteLine(func(1, 2));
}

Lambda表达式

Func<int, int, string> f1 = (i1,i2) =>{return $"{i1}+{i2}={i1 + i2}";
};
  • 可以省略参数数据类型,因为编译能根据委托类型推断出参数的类型,用=>引出来方法体。
  • 如果委托没有返回值,且方法体只有一行代码,可省略 {}
  • 如果=>之后的方法体中只有一行代码,且方法有返回值,那么可以省略方法体的{}以及return。
  • 如果只有一个参数,参数的()可以省略。

2、.NET 中定义了泛型委托Action(无返回值)和Func(有返回值),所以一般不用自定义委托类型。

static void Main(string[] args)
{Action a = F1;a();
}
static void F1()
{Console.WriteLine("hello");
}
static void Main(string[] args)
{Func<int, int, int> func = F2;int sum = func(2, 5);Console.WriteLine(sum);
}
static int F2(int a, int b)
{return a + b;
}

LINQ

筛选出数组中大于3的数字:

IEnumerable<int> ints = [ 2,3,4,5,5];
IEnumerable<int> result = ints.Where(a => a > 3);

通过编写扩展方法MyWhere来模拟Where的实现:

static void Main(string[] args)
{IEnumerable<int> ints = [ 2,3,4,5,5];//IEnumerable<int> result = ints.Where(a => a > 3);IEnumerable<int> result = MyWhere(ints, a => a > 3);foreach (var item in result){Console.WriteLine(item);}
}static IEnumerable<int> MyWhere(IEnumerable<int> ints, Func<int, bool> func)
{List<int> result = new List<int>();foreach (var item in ints){if(func(item)) result.Add(item);}return result;
}

yield return

通过yield return来让MyWhere“流水线”处理:

static void Main(string[] args)
{IEnumerable<int> ints = [ 2,3,4,5,5];//IEnumerable<int> result = ints.Where(a => a > 3);IEnumerable<int> result = MyWhere(ints, a => a > 3);foreach (var item in result){Console.WriteLine(item);}
}
static IEnumerable<int> MyWhere(IEnumerable<int> ints, Func<int, bool> func)
{List<int> result = new List<int>();foreach (var item in ints){if(func(item)) yield return item;}
}

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

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

相关文章

管理的常识--决策如何有效计划控制

决策的目的是为了执行 决策决定你的选择 决策是为了能够执行&#xff0c;而不是追求正确性&#xff1b;或者说决策正确性指的不是决策本身&#xff0c;而是决策得到执行的结果 决策是要解决问题而不是简单做出选择&#xff0c;如果简单做出选择&#xff0c;只是完成了决策的过…

kafka学习笔记01(小滴课堂)

介绍分布式流处理平台kafka快速认知 介绍分布式流处理平台kafka核心概念解释 急速部署-Kafka相关环境准备和安装 Linux环境下Zookeeper和Kafka安装启动 解压两个软件的压缩包&#xff1a; tar -zxvf 启动zk: 去log目录进行查看&#xff1a; 查看一下2181端口是否被占用: 安装…

Python实战:Python虚拟环境(venv)的创建与使用

一、引言 在Python开发中&#xff0c;项目之间的依赖管理是一个常见问题。不同的项目可能需要不同的Python版本或依赖库。为了解决这个问题&#xff0c;我们可以使用Python虚拟环境&#xff08;venv&#xff09;。虚拟环境是一种隔离的Python环境&#xff0c;它允许我们为每个…

十九、网络编程

目录 一、什么是网络编程二、网络编程三要素2.1 IP2.2 InetAddress的使用2.3 端口号2.4 协议 三、UDP通信程序3.1 发送数据3.2 接收数据3.3 练习 四、UDP的三种通信方式五、TCP的通信程序六、三次握手和四次挥手七、练习7.1 TCP通信练习1——多发多收7.2 TCP通信练习2——接收和…

80386 ATT汇编语法

文章目录 gcc的预处理&#xff0c;不进行编译、汇编或链接预处理编译汇编 8.8.2 AT&T语法与英特尔语法8.8.3操作码命名8.8.4寄存器命名8.8.5操作码前缀8.8.6内存引用8.8.7跳转指令的处理8.8.8浮点8.8.9写入16位代码8.8.10笔记 gcc的预处理&#xff0c;不进行编译、汇编或链…

Java疫苗接种管理系统

本系统lw为2024-3-21本人原创&#xff0c;查chong13% 1.3W字&#xff0c;可以直接上交&#xff0c;这并不是乱七八糟的技术文档和项目文档。 4.2 功能结构设计 可视化的疫苗接种管理系统功能结构设计主要包括以下几个模块&#xff1a; 登录注册模块&#xff1a;这个模块负责…

浅浅迈入C++门槛

从今天起&#xff0c;我要开始hello&#xff0c;world。 往后更要做到&#xff0c;拳打数据结构&#xff0c;脚踢Linux。 这就是江湖人的风范。 拼搏百天&#xff0c;我要学希普拉斯普拉斯。 C是在C的基础之上&#xff0c;容纳进去了面向对象编程思想&#xff0c;并增加了许…

vmware中ubuntu虚拟机桥接模式和xshell连接

首先&#xff0c;把虚拟机的虚拟机设置那里改成桥接模式&#xff0c;然后电脑本地用的什么网&#xff0c;就拿对应的网卡在vmware的虚拟网络编辑器那里去改第一个成桥接&#xff0c;添加这个网卡去虚拟 之后去ubuntu右上角把ip设置成手动&#xff0c; ip前三个表示网段的和本…

echarts实践总结(常用二):折线图(特点:渐变、面积区域)

目录 第一章 echarts基本使用 第二章 echarts实践——折线图 效果展示 第一章 echarts基本使用 Echarts常用配置项(详细入门)_echarts配置项手册-CSDN博客 柱状图案例&#xff1a; echarts实践总结(常用一)&#xff1a;柱状图&#xff08;特点&#xff1a;渐变色、点击缩放、…

vue3父子通信、跨层通信

子传父 通过 ref标识 获取真实的 dom对象或者组件实例对象 父组件获取子组件内部属性和方法 顶层组件向任意的底层组件传递数据和方法&#xff0c;实现跨层组件通信 非响应式数据父修改不了子的内容 子组件调用父组件方法

【Markdown】【mermaid】Mermaid 简介:使用Markdown动态创建和修改图表

Mermaid 简介 什么是 Mermaid图表类型1. 流程图 (Flowchart)2. 序列图 (Sequence diagram)3. 甘特图 (Gantt diagram)4. 类图 (Class diagram)5. Git 图 (Git graph)6. 实体关系图 (Entity Relationship Diagram)7. 用户旅程图 (User Journey Diagram)8. 象限图 (Quadrant Char…

【现代C++】范围基于的for循环

现代C中的范围基于的for循环&#xff08;range-based for loop&#xff09;是C11引入的一项特性&#xff0c;旨在简化对容器或范围的迭代过程。这种循环语法不仅使代码更清晰易读&#xff0c;还减少了迭代时的错误。以下是范围基于的for循环的详细介绍&#xff1a; 1. 基本用法…

CTK插件框架学习-源码下载编译(01)

1、编译环境 window11、vs17、Qt5.14.0、cmake3.27.4 2、下载链接 cmake&#xff1a;Index of /files/v3.20 qt&#xff1a;Index of / vs22以前的版本需要登录下载&#xff1a;Visual Studio 较旧的下载 - 2019、2017、2015 和以前的版本 vs22下载&#xff1a;下载 Visu…

华为OD机试真题实战应用【赛题代码篇】-整数与IP地址间的转换(附Java、C++和python代码实现)

目录 问题描述 输入描述: 输出描述: 示例: 代码实现 Java 代码2 代码3

Arduino IDE工程代码多文件编程和中文设置

一、esp8266模块信息 二、中英文切换 点击文件( File )–选择首选项( Preference )—选择语言( Language )—选择中文–点击确定( OK ) 三、多文件编程 在Arduino编程中&#xff0c;将代码分割成多个文件是一种很好的做法&#xff0c;特别是项目变得越来越大和复杂时。这样…

Linux 系统是如何收发⽹络包的

Linux 系统是如何收发⽹络包的&#xff1f; ⽹络模型 为了使得多种设备能通过⽹络相互通信&#xff0c;和为了解决各种不同设备在⽹络互联中的兼容性问题&#xff0c;国际标准化组织制定了开放式系统互联通信参考模型&#xff08;Open System Interconnection Reference Mode…

亚马逊云科技:企业如何开启生成式AI之旅?

如果要评选最近两年全球科技行业最热门的细分领域&#xff0c;那么生成式AI绝对会以遥遥领先的票数成为当仁不让的冠军。 然而眼见生成式AI发展得如火如荼&#xff0c;越来越多的企业却陷入了深深的焦虑&#xff1a;应该如何开启生成式AI之旅&#xff1f;又该怎样搭建大模型&am…

对七层代理、四层代理、正向代理、反向代理的认识

一、理解nginx服务代理 Nginx代理有正向和反向代理两种类型&#xff0c;可以基于osi七层模型中的第四层&#xff08;传输层&#xff09;和第七层&#xff08;应用层&#xff09;进行代理 注&#xff1a; nginx 一般支持的是7层代理&#xff0c;支持四层代理一般使用 lvs 或者ha…

Data.olllo:一键去除相同内容数据列!

引言&#xff1a; 在数据处理的舞台上&#xff0c;重复数据常常像调皮的小精灵一样&#xff0c;频繁出现&#xff0c;让人头疼不已。但现在&#xff0c;有了Data.olllo的神奇功能&#xff0c;您可以一键去除相同内容数据列&#xff0c;让数据处理变得轻松愉快&#xff01; 功能…

Android中广播的基本介绍

文章目录 1. 广播的概念2. 广播的基本组成2.1 广播发送器2.2 广播接收器 3. 广播注册3.1 动态注册3.2 静态注册 1. 广播的概念 BroadcastReceiver&#xff0c;广播接收器&#xff0c;是Android四大组件之一&#xff0c;可用来跨进程通信的一种机制。当然&#xff0c;也可以用于…