C#“.NET技术” 中奇妙的函数--联接序列的五种简单方法

简介:   今天我们来看看5种使用Linq函数联接序列的方法,这5种方法可以归入下列两类:  同类的联接  Concat()  Union()  不同类的联接  Zip()  Join()  GroupJoin()  Concat() – 串联序列  最简单的序列合并,concat仅仅是将第二个序列接在第一个序列后面, 注意:返回的序列并没有改变原来元素的顺序: 1.

  今天我们来看看5种使用Linq函数联接序列的方法,这5种方法可以归入下列两类:

  同类的联接

  Concat()

  Union()

  不同类的联接

  Zip()

  Join()

  GroupJoin()

  Concat() – 串联序列

  最简单的序列合并,concat仅仅是将第二个序列接在第一个序列后面, 注意:返回的序列并没有改变原来元素的顺序:

 
 
1 . var healthFoods = new List < string > { " fruits " , " vegetables " , " grains " , " proteins " };
2 . var myFoods = new List < string > { " grains " , " proteins " , " M&Ms " , " soda " };
3 . // 返回序列: fruits, vegetables, grains, proteins, grains, proteins, M&Ms, soda
4 . var healthyFirst = healthFoods.Concat(myFoods);
5 . // 返回序列: grains, proteins, M&Ms, soda, fruits, vegetables, grains, proteins
6 . var mineFirst = myFoods.Concat(healthFoods);

  Union() – 无重复项的串联序列

  该方法用于结合两个没有重复项的集合,也非常适用于任何两个序列。 它将第二个序列结合到第一个序列里,当第二个序列中出现与第一个序列重复的项时,它只保留第一序列的项目。

  是否是重复的项目取决于IEqualityComparer <T> ,如果你没有提供个性化的定义,则使用该类型的默认函数。 请注意,如果 T 是一个自定义的类型,这意味着你同时需要一个有效的Equals() 和 GetHashCode()的定义。

 
 
1 . // 返回序列: fruits, vegetables, grains, proteins, M&Ms, soda
2 . var healthyFirst = healthFoods.Union(myFoods);
3 . // 返回序列: grains, proteins, M&Ms, soda, fruits, vegetables
4 . var mineFirst = myFoods.Union(healthFoods);

  Zip() – 简单一对一的联接

  该方法针对两个不同类执行一个最简单的联接。 比如给定两个序列,它仅仅将他们的第一个项合并,而后将他们第二个项合并,…,一旦到达较短序列的最后一项,它就会立即停止。

  比方说,比如,我们有下面的类定义:

 
 
1 . public class Employee
2 . {
3 . public int Id { get ; set ; }
4 . public string Name { get ; set ; }
5 . public double Salary { get ; set ; }
6 . }
7 . public class Seat
8 . {
9 . public int Id { get ; set ; }
10 . public double Cost { get ; set ; }
11 . }

  然后,我们确定了以下顺序:

 
 
1 . var employees = new List < Employee >
2 . {
3 . new Employee { Id = 13 , Name = " John Doe " , Salary = 13482.50 },
4 . new Employee { Id = 42 , Name = " Sue Smith " , Salary = 98234.13 },
5 . new Employee { Id = 99 , Name = " Jane Doe " , Salary = 32421.12 }
6 . };
7 . var seats = new List < Seat >
8 . {
9 . new Seat { Id = 1 , Cost = 42 },
10 . new Seat { Id = 2 , Cost = 42 },
11 . new Seat { Id = 3 , Cost = 100 },
12 . new Seat { Id = 4 , Cost = 100 },
13 . new Seat { Id = 5 , Cost = 125 },
14 . new Seat { Id = 6 , Cost = 125 },
15 . };

  我们可以联接它们,给每个雇员提供一个座位: 

 
 
1 . var seatingAssignments = employees.Zip(seats, (e, s) => new
上海企业网站制作>2 . { EmployeeId = e.Id, SeatId = s.Id });
3 . foreach (var seat in seatingAssignments)
4 . {
5 . Console.WriteLine( " 雇员: " + seat.EmployeeId + " 预约了座位 " + seat.SeatId);
6 .
7 . }

  我们可以得到:

  雇员: 13 预约了座位1

  雇员: 42 预约了座位2

  雇员: 99 预约了座位3

  Join() – 满足条件的联接

  “使用 join 子句可以将来自不同源序列并且在对象模型中没有直接关系的元素相关联。 唯一的要求是每个源中的元素需要共享某个可以进行比较以判断是否相等的值。 例如,食品经销商可能具有某种产品的供应商列表以及买主列表。 例如,可以使用 join 子句创建该产品同一指定地区供应商和买主的列表。

  join 子句接受两个源序列作为输入。 每个序列中的元素都必须是可以与另一个序列中的相应属性进行比较的属性,或者包含一个这样的属性。 join 子句使用特殊的 equals 关键字比较指定的键是否相等。 join 子句执行的所有联接都是同等联接。 join 子句的输出形式取决于所执行的联接的具体类型。 ”

  是否相等取决于IEqualityComparer<T>,如果你使用自定义的类型,你需要提供 Equals() 和 GetHashCode() 或者提供一个自定义的 IEqualityComparer<T>. 但是你使用的.NET 中的类型,则一般不需要再另外实现这些函数。

  上例子,使用之前的Employee类,再加一个Badge类,然后我们再创建这一组序列:

 
 
1 . public class Badge
2 . {
3 . public int EmployeeId { get ; set ; }
4 . public int BadgeNumber { get ; set ; }
5 . }
6 . var employees = new List < Employee >
7 . {
8 . new Employee { Id = 13 , Name = " John Doe " , Salary = 13482.50 },
9 . new Employee { Id = 42 , Name = " Sue Smith " , Salary = 98234.13 },
10 . new Employee { Id = 99 , Name = " Jane Doe " , Salary = 32421.12 }
11 . };
12 . var badges = new List < Badge >
13 . {
14 . new Badge { EmployeeId = 10 , BadgeNumber = 1 },
15 . new Badge { EmployeeId = 13 , BadgeNumber = 2 },
16 . new Badge { EmployeeId = 20 , BadgeNumber = 3 },
17 . new Badge { EmployeeId = 25 , BadgeNumber = 4 },
18 . new Badge { EmployeeId = 42 , BadgeNumber = 5 },
19 . new Badge { EmployeeId = 10 , BadgeNumber = 6 },
20 . new Badge { EmployeeId = 13 , BadgeNumber = 7 },
21 . };

  这样我们就可以使用Join 来对它们进行操作了:

 
 
1 . var badgeAssignments = employees.Join(badges, e => e.Id, b => b.EmployeeId,
2 . (e, b) => new { e.Name, b.BadgeNumber });
3 . foreach (var badge in badgeAssignments)
4 . {
5 . Console.WriteLine( " Name: " + badge.Name + " has badge " + badge.BadgeNumber);
6 . }

  返回的结果是:

  Name: John Doe has badge 2

  Name: John Doe has badge 7

  Name: Sue Smith has badge 5

  Join 对于1:1的关系是非常实用的,或者如果你不在乎返回一些重复的1:N的关系,你也可以是用Join.

  GroupJoin() – 适用于一对多的条件联接

  那么,如果你有1:N的关系,你希望这些结果分类组合在一起就可以用到 GroupJoin(),仍旧用上面的例子:

 
 
1 . var badgeAssignments = employees.GroupJoin(badges, e => e.Id, b => b.EmployeeId,
2 . (e, bList) => new { Name = e.Name, Badges = bList.ToList() });
3 . foreach (var assignment in badgeAssignments)
4 . {
5 . Console.WriteLine(assignment.Name + " has badges: " );
6 . if (assignment.Badges.Count > 0 )
7 . {
8 . foreach (var badge in assignment.Badges)
9 . {
10 . Console.WriteLine( " \tBadge: " + badge.BadgeNumber);
11 . }
12 . }
13 . else
14 . {
15 . Console.WriteLine( " \tNo badges. " );
16 . }
17 . }

  结果如下:

 
 
1 . John Doe has badges:
2 . Badge: 2
3 . Badge: 7
4 . Sue Smith has badges:
5 . Badge: 5
6 . Jane Doe has badges:
7 . No badges.

  如果你想进步一强化对Join 和 GroupJoin 区别的了解,可以再一次看看上面两个例子输入的结果。

目录
相关文章
|
4月前
|
API C++ Windows
Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法
本文介绍Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法,提供官方下载链接与系统修复工具使用指南。
912 2
|
4月前
|
监控 Cloud Native 测试技术
.NET技术深度解析:现代企业级开发指南
每日激励:“不要一直责怪过去的自己,他曾经站在雾里也很迷茫”。我是蒋星熠Jaxonic,一名在代码宇宙中探索的极客旅人。从.NET Framework到.NET 8,我深耕跨平台、高性能、云原生开发,践行领域驱动设计与微服务架构,用代码书写技术诗篇。分享架构演进、性能优化与AI融合前沿,助力开发者在二进制星河中逐光前行。关注我,共探技术无限可能!
.NET技术深度解析:现代企业级开发指南
|
10月前
|
SQL 小程序 API
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
407 0
|
开发框架 算法 .NET
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
226 6
|
开发框架 Cloud Native .NET
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
241 6
|
机器学习/深度学习 人工智能 Cloud Native
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台。本文深入解析 .NET 的核心优势,探讨其在企业级应用、Web 开发及移动应用等领域的应用案例,并展望未来在人工智能、云原生等方面的发展趋势。
284 3
|
5月前
|
XML 前端开发 C#
C#编程实践:解析HTML文档并执行元素匹配
通过上述步骤,可以在C#中有效地解析HTML文档并执行元素匹配。HtmlAgilityPack提供了一个强大而灵活的工具集,可以处理各种HTML解析任务。
278 19
|
6月前
|
监控 算法 C#
C#与Halcon联合编程实现鼠标控制图像缩放、拖动及ROI绘制
C#与Halcon联合编程实现鼠标控制图像缩放、拖动及ROI绘制
1037 0
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
311 3
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
1042 12