網站首頁 編程語言 正文
前言
如標題所述,在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
到這里引用類型的比較已經完成了,比較器的條件方法可以根據需求調整,如有不足之處,希望大家多多指正!!!
原文鏈接:https://www.cnblogs.com/wslpf/p/16527639.html
相關推薦
- 2022-09-26 go使用makefile腳本編譯應用的方法小結_Golang
- 2022-04-16 python案例練習合集_python
- 2022-03-11 UE4 添加自己項目的AutomationProject,解決報錯Failed to find co
- 2022-12-31 一文初探Go語言中的reflect反射包_Golang
- 2022-11-03 C語言編寫掃雷小程序_C 語言
- 2023-02-07 C#實現加密bat文件的示例詳解_C#教程
- 2022-04-15 基于Redis?zSet實現滑動窗口對短信進行防刷限流的問題_Redis
- 2022-08-18 Linux阿里云服務器中安裝Nginx命令的詳細過程_服務器其它
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支