Linq中的设置操作 (C#):Distinct 和 DistinctBy、Except 和 ExceptBy、Intersect 和 IntersectBy、Union 和 UnionBy

news/2025/1/9 20:19:43/文章来源:https://www.cnblogs.com/lgx5/p/18662841

LINQ 中的集运算是指根据相同或单独集合中是否存在等效元素来生成结果集的查询运算。

注:这些示例使用 System.Collections.Generic.IEnumerable<T> 数据源。 基于 System.Linq.IQueryProvider 的数据源使用 System.Linq.IQueryable<T> 数据源和表达式树。 表达式树对允许的 C# 语法有限制。 此外,每个 IQueryProvider 数据源(如 EF Core)可能会施加更多限制。

1、Distinct 和 DistinctBy

以下示例演示字符串序列上 Enumerable.Distinct 方法的行为。 返回的序列包含输入序列的唯一元素。

 

string[] words = ["the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"];IEnumerable<string> query = from word in words.Distinct()select word;foreach (var str in query)
{Console.WriteLine(str);
}/* This code produces the following output:** the* quick* brown* fox* jumped* over* lazy* dog*/

DistinctBy 是 Distinct 的替代方法,它采用 keySelector。 keySelector 用作源类型的比较鉴别器。 在以下代码中,单词根据其 Length 进行区分,并且显示每个长度的第一个单词:

string[] words = ["the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"];foreach (string word in words.DistinctBy(p => p.Length))
{Console.WriteLine(word);
}// This code produces the following output:
//     the
//     quick
//     jumped
//     over

2、Except 和 ExceptBy

1)Except

以下示例演示 Enumerable.Except 的行为。 返回的序列只包含位于第一个输入序列但不位于第二个输入序列的元素。

 

string[] words1 = ["the", "quick", "brown", "fox"];
string[] words2 = ["jumped", "over", "the", "lazy", "dog"];IEnumerable<string> query = from word in words1.Except(words2)select word;foreach (var str in query)
{Console.WriteLine(str);
}/* This code produces the following output:** quick* brown* fox*/

2)ExceptBy

方法是 Except 的替代方法,它采用可能是异构类型的两个序列和一个 keySelector。 keySelector 的类型与第一个集合的类型相同。 请考虑以下要排除的 Teacher 数组和教师 ID。 若要查找第一个集合中没有出现在第二个集合中的教师,可以将教师的 ID 投影到第二个集合中:

本文中的以下示例使用此区域的常见数据源。
每个 Student 都有年级、主要院系和一系列分数。 Teacher 还有一个 City 属性,用于标识教师的授课校区。 Department 有一个名称,以及对担任院系主任的 Teacher 的引用。

public enum GradeLevel
{FirstYear = 1,SecondYear,ThirdYear,FourthYear
};public class Student
{public required string FirstName { get; init; }public required string LastName { get; init; }public required int ID { get; init; }public required GradeLevel Year { get; init; }public required List<int> Scores { get; init; }public required int DepartmentID { get; init; }
}public class Teacher
{public required string First { get; init; }public required string Last { get; init; }public required int ID { get; init; }public required string City { get; init; }
}public class Department
{public required string Name { get; init; }public int ID { get; init; }public required int TeacherID { get; init; }
}
int[] teachersToExclude =
[901,    // English965,    // Mathematics932,    // Engineering945,    // Economics987,    // Physics901     // Chemistry
];foreach (Teacher teacher inteachers.ExceptBy(teachersToExclude, teacher => teacher.ID))
{Console.WriteLine($"{teacher.First} {teacher.Last}");
}

在以上 C# 代码中:

已筛选 teachers 数组以仅包含不在 teachersToExclude 数组中的那些教师。
teachersToExclude 数组包含所有部门负责人的 ID 值。
对 ExceptBy 的调用会生成一个新的值集,这些值被写入到控制台。
新的值集的类型为 Teacher,这是第一个集合的类型。 对于 teachers 数组中的每个 teacher,如果在 teachersToExclude 数组中没有相应 ID 值,则会写入到控制台。

3、Intersect 和 IntersectBy

1)Intersect

以下示例演示 Enumerable.Intersect 的行为。 返回的序列包含两个输入序列共有的元素。

string[] words1 = ["the", "quick", "brown", "fox"];
string[] words2 = ["jumped", "over", "the", "lazy", "dog"];IEnumerable<string> query = from word in words1.Intersect(words2)select word;foreach (var str in query)
{Console.WriteLine(str);
}/* This code produces the following output:** the*/

2)IntersectBy

IntersectBy 方法是 Intersect 的替代方法,它采用可能是异构类型的两个序列和一个 keySelector。 keySelector 用作第二个集合类型的比较鉴别器。 请考虑以下学生和教师数组。 查询按名称匹配每个序列中的项,以查找那些也是教师的学生:

foreach (Student person instudents.IntersectBy(teachers.Select(t => (t.First, t.Last)), s => (s.FirstName, s.LastName)))
{Console.WriteLine($"{person.FirstName} {person.LastName}");
}

在上述 C# 代码中:

该查询通过比较名称生成 Teacher 和 Student 的交集。
只有在这两个阵列中都找到的人员才会出现在结果序列中。
将生成的 Student 实例写入控制台。

4、Union 和 UnionBy

1)Union

以下示例演示对两个字符串序列执行的联合操作。 返回的序列包含两个输入序列的唯一元素。

 

string[] words1 = ["the", "quick", "brown", "fox"];
string[] words2 = ["jumped", "over", "the", "lazy", "dog"];IEnumerable<string> query = from word in words1.Union(words2)select word;foreach (var str in query)
{Console.WriteLine(str);
}/* This code produces the following output:** the* quick* brown* fox* jumped* over* lazy* dog
*/

2)UnionBy

UnionBy 方法是 Union 的替代方法,它采用相同类型的两个序列和一个 keySelector。 keySelector 用作源类型的比较鉴别器。 以下查询生成所有人员(学生或教师)的列表。 同时也是教师的学生只会被添加到并集中一次:

foreach (var person instudents.Select(s => (s.FirstName, s.LastName)).UnionBy(teachers.Select(t => (FirstName: t.First, LastName: t.Last)), s => (s.FirstName, s.LastName)))
{Console.WriteLine($"{person.FirstName} {person.LastName}");
}

在上述 C# 代码中:

  • teachers 和 students 数组使用其名称作为键选择器编织在一起。
  • 生成的名称将写入控制台。

 



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

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

相关文章

2025多校冲刺省选模拟赛3

过于困难,直接放弃2025多校冲刺省选模拟赛3\(T1\) A. 等差 \(100pts/100pts\)考虑哈希,每 \(k\) 个作为一组与上一组统一计算。取 \(Base>\) 值域时用高精度来存储并判断的正确性显然。观察到可行的最小的 \(k\) 单调不降,不妨直接枚举答案。暴力实现时间复杂度为 \(O(n…

还不会 Cert Manager 自动签发证书?一文掌握

相信很多小伙伴对于 Cert Manager 不陌生,Cert Manager 是 Kubernetes 上的证书管理工具,基于 ACME 协议与 Lets Encrypt 签发免费证书并为证书自动续期,实现永久免费使用证书。 本文将介绍如何使用 Cert Manager 实现自动签发证书并与 Rainbond 结合使用。 Cert Manager 概…

JAVA-Day 09:While循环语句

While循环 while循环格式 初始化语句; while(条件判断语句){ 循环体语句; 条件控制语句; } 初始化语句只执行一次 判断语句为True,循环继续 判断语句为False,循环结束 例: 世界最高山峰珠穆朗玛峰的高度为8844.43米=8844430毫米,假如有 一张足够大的纸,它的厚度为0.1毫米。…

rust学习十六.2、并发-利用消息传递进行线程间通讯

通过信道是rust的解决线程之间通信的2个工具之一,另外1个是是共享内存状态。 rust推出这个,明显地是因为受到go之类的影响。 在书籍中,作者提到go编程文档中的内容: 不要通过共享内存来通讯;而是通过通讯来共享内存(Do not communicate by sharing memory; instead, share…

2025,谁会成为 AI Agent 的新入口?|播客《编码人声》

「编码人声」是由「RTE开发者社区」策划的一档播客节目,关注行业发展变革、开发者职涯发展、技术突破以及创业创新,由开发者来分享开发者眼中的工作与生活。2024 年末,一群来自 Android、Chrome OS、Oculus 等操作系统的开发元老联合创业,推出 AI Agent 操作系统 /dev/agen…

【Windows内核】Ntdll解除挂钩学习

简介 我们之前都是直接通过使用直接系统调用的方式来绕过用户态钩子,通过在项目文件中创建并调用系统调用来实现此目标。还有另外一种方法也可以绕过用户态的钩子,那么这种方法是将已经加载到进程中的钩子DLL替换为一个未经修改且未被钩主的版本来达到相同的目标。 将勾住的D…

21. 主窗口控件

一、主窗口控件之前,我们使用可视控件创建具体的实例时都选择了一个父窗体,将控件放到这个窗体上,即使在创建实例时没有选择父窗体,也可以用控件的 setParent() 方法将控件放到父窗体上。如果一个控件没有放到任何窗体上,则这个控件可以单独成为窗口,并且可以作为父窗口来…

智慧帮手:一站式搭建帮助中心,优化客户服务体验

在数字化时代,客户服务已成为企业赢得市场、留住客户的关键。一个高效、便捷的帮助中心,不仅能够快速响应客户需求,还能提升客户满意度和忠诚度。然而,如何搭建一个既满足客户需求又符合企业特色的帮助中心,成为众多企业面临的挑战。本文将探讨如何借助一站式解决方案,如…

解锁餐饮新篇:精准搭建内部知识库,赋能高效运营

在当今竞争激烈的餐饮行业中,提升运营效率和服务质量已成为企业脱颖而出的关键。随着餐饮业务的不断扩展,内部信息管理和知识传承成为了一大挑战。如何构建一个高效、精准的内部知识库,成为解锁餐饮新篇章的重要一环。本文将探讨如何借助智能化工具,如HelpLook,实现这一目…

【YashanDB知识库】进行load data的时候报找不到动态库liblz4.so

本文内容来自YashanDB官网,原文内容请见 https://www.yashandb.com/newsinfo/7863047.html?templateId=1718516 现象 23.2版本的依赖项准备里指明,要依赖动态库:liblz4.so,liblz4.so.1,liblz4.so.1.9.3 在执行load data的时候报找不到动态库liblz4.so 操作系统在/lib64/目…

JAVA-Day 08:For循环语句

For循环 For循环格式 for循环语句格式 for(初始化语句;条件判断语句;条件控制语句){ 循环语句体; } 执行流程: 1、执行初始化语句 2、执行条件判断语句,看其结果是True还是False,如果是True,执行循语句体,如果是False,循环结束 3、执行条件控制语句 4、回到2继续执行条件判…

记录---JS 的蝴蝶效应 —— 事件流

🧑‍💻 写在开头 点赞 + 收藏 === 学会🤣🤣🤣前言 在 JavaScript 的世界里,事件流就像一只永不停歇的蝴蝶,每一个动作、每一个点击、每一个滚动,都会触发一连串的蝴蝶效应。作为一名开发者,掌握事件流的艺术,不仅能让你的网页更加生动、更加交互,也能让用户体验…