.NET中求复杂类型集合的差集、交集、并集
前言
如标题所述,在ASP.NET应用程序开发中,两个集合做比较时 我们使用微软IEnumerable封装的Except/Intersect/Union取 差集/交集/并集 方法是非常的方便的;
但以上对于不太熟悉的小伙伴来讲,在遇到求包含引用类型(不包含string)集合时就非常的苦恼;
下面我将带着大家去了解如何通过微软自带方法方式去取**复杂类型集合**的差集、交集、并集。
场景
这里是场景,我有以下两个学生集合。
namespace Test2 { internal class Program { public void Main() { //列表1 List<Student> StudentList1 = new List<Student>() { new Student {Id=1,Name="小明",Age=27 }, new Student {Id=3,Name="大郭",Age=28 }, new Student {Id=4,Name="老登",Age=29 } }; List<Student> StudentList2 = new List<Student>() { new Student {Id=1,Name="小明",Age=27 }, new Student {Id=3,Name="大郭",Age=28 }, new Student {Id=4,Name="老登",Age=29 }, new Student {Id=4,Name="小路",Age=28 }, new Student {Id=4,Name="小明",Age=30 } }; } } }
生成两个实体集合;
下面我们取交集/差集/并集
完整调用示例(.NET Core):
namespace Test2 { internal class Program { public static void Main() { //列表1 List<Student> StudentList1 = new List<Student>() { new Student {Id=1,Name="小明",Age=27 }, new Student {Id=2,Name="大郭",Age=28 }, new Student {Id=3,Name="老登",Age=29 } }; //列表2 List<Student> StudentList2 = new List<Student>() { new Student {Id=1,Name="小明",Age=27 }, new Student {Id=2,Name="大郭",Age=28 }, new Student {Id=3,Name="老登",Age=29 }, new Student {Id=4,Name="小路",Age=28 }, new Student {Id=5,Name="小明",Age=30 } }; //取比列表1里多出来的学生数据 并输出 var ExceptData = StudentList2.Except(StudentList1); Console.WriteLine("差集:" + String.Join(";", ExceptData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; }))); //取列表1与列表2里共有的学生数据 var IntersectData = StudentList1.Intersect(StudentList2); Console.WriteLine("交集:" + String.Join(";", IntersectData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; }))); //获取办理所有学生的数据(一个相同的学生只能一条) var UnionData = StudentList1.Union(StudentList2); Console.WriteLine("并集:"+String.Join(";", UnionData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; }))); } } }
输出:
差集:1-小明-27;2-大郭-28;3-老登-29;4-小路-28;5-小明-30
交集:null
并集:1-小明-27;2-大郭-28;3-老登-29;1-小明-27;2-大郭-28;3-老登-29;4-小路-28;5-小明-30
以上输出仔细看一下明显是不对的,这就涉及到了复杂类型对比,请看代码:
正常我们声明的类
/// <summary> /// 学生类 /// </summary> internal class Student { /// <summary> /// 编号 /// </summary> public int Id { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 年龄 /// </summary> public int Age { get; set; } }
因为我们要对比的是引用类型,因为在对比除string引用类型外,其他引用类型的对比默认都是对比的堆里地址,所以我们要实现一个自定义的对比方案
我们需要继承一个接口IEqualityComparer<T> 泛型接口
如下:(这里我们以年龄与名做为对比条件)
/// <summary> /// 学生类 /// </summary> internal class Student : IEqualityComparer<Student> { /// <summary> /// 编号 /// </summary> public int Id { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 年龄 /// </summary> public int Age { get; set; } /// <summary> /// 比较器 /// </summary> /// <param name="s1">比较实体1</param> /// <param name="s2">比较实体2</param> /// <returns></returns> public bool Equals(Student s1, Student s2) { //验证相等条件 if (s1.Name == s2.Name && s1.Age == s2.Age) { return true; } return false; } /// <summary> /// 获取唯一条件 /// </summary> /// <param name="stu"></param> /// <returns></returns> public int GetHashCode(Student stu) { return (stu.Name + "|" + stu.Age).GetHashCode(); } }
修改了类后还有最重要的一点:就是修改比较的方法(相当于声明一个自定义的比较器给方法)
//取比列表1里多出来的学生数据 并输出 var ExceptData = StudentList2.Except(StudentList1,new Student()); Console.WriteLine("差集:" + String.Join(";", ExceptData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; }))); //取列表1与列表2里共有的学生数据 var IntersectData = StudentList1.Intersect(StudentList2,new Student()); Console.WriteLine("交集:" + String.Join(";", IntersectData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; }))); //获取办理所有学生的数据(一个相同的学生只能一条) var UnionData = StudentList1.Union(StudentList2,new Student()); Console.WriteLine("并集:"+String.Join(";", UnionData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; })));
输出:
差集:4-小路-28;5-小明-30
交集:1-小明-27;2-大郭-28;3-老登-29
并集:1-小明-27;2-大郭-28;3-老登-29;4-小路-28;5-小明-30
到这里引用类型的比较已经完成了,比较器的条件方法可以根据需求调整,如有不足之处,希望大家多多指正!!!
到此这篇关于.NET的求复杂类型集合的差集、交集、并集的文章就介绍到这了,更多相关.net差集、交集、并集内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
asp.net core webapi 服务端配置跨域的实例
下面小编就为大家分享一篇asp.net core webapi 服务端配置跨域的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2017-12-12详解.net core webapi 前后端开发分离后的配置和部署
这篇文章主要介绍了.net core webapi 前后端开发分离后的配置和部署,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-04-04使用Entity Framework(4.3.1版本)遇到的问题整理
在这里记录一下之前使用Entity Framework(4.3.1版本)遇到的问题:更新没有设置主键的表、更改Code-First的默认连接、检测字符串截断错误,需要的朋友可以参考下2012-12-12
最新评论