關於List的交集和並集的東西,上代碼
class Program { static void Main(string[] args) { List<Fish> a = new List<Fish>(); a.Add(new Fish() {Name="測試1",ID=0,Message="" }); a.Add(new Fish() { Name = "測試2", ID = 1, Message = "" }); a.Add(new Fish() { Name = "測試3", ID = 2, Message = "" }); a.Add(new Fish() { Name = "測試4", ID = 3, Message = "" }); List<Fish> b = new List<Fish>(); b.Add(new Fish() { Name = "測試1", ID = 0, Message = "" }); b.Add(new Fish() { Name = "測試3", ID = 5, Message = "" }); b.Add(new Fish() { Name = "測試5", ID = 6, Message = "" }); List<Fish> c = a.Union(b).ToList();
//List<Fish> c = a.Intersect(b).ToList(); foreach (var item in c) { Console.WriteLine("Name:{0},ID:{1}", item.Name, item.ID); } Console.ReadLine(); } } public class Fish { public string Name { get; set; } public int ID { get; set; } public string Message { get; set; } }
一個簡單的測試類有三個屬性,現在我想取a和b的並集,結果如下:
結果並不是我想要的,“測試1”這個結果應該顯示一次就夠了,而 List<Fish> c = a.Intersect(b).ToList();顯示的結果更是空白,這是怎么回事兒?
來看一下Union的原型
// // 摘要: // 通過使用默認的相等比較器生成兩個序列的並集。 // // 參數: // first: // 一個 System.Collections.Generic.IEnumerable<T>,它的非重復元素構成聯合的第一個集。 // // second: // 一個 System.Collections.Generic.IEnumerable<T>,它的非重復元素構成聯合的第二個集。 // // 類型參數: // TSource: // 輸入序列中的元素的類型。 // // 返回結果: // 一個 System.Collections.Generic.IEnumerable<T>,包含兩個輸入序列中的元素(重復元素除外)。 // // 異常: // System.ArgumentNullException: // first 或 second 為 null。 public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second); // // 摘要: // 通過使用指定的 System.Collections.Generic.IEqualityComparer<T> 生成兩個序列的並集。 // // 參數: // first: // 一個 System.Collections.Generic.IEnumerable<T>,它的非重復元素構成聯合的第一個集。 // // second: // 一個 System.Collections.Generic.IEnumerable<T>,它的非重復元素構成聯合的第二個集。 // // comparer: // 用於對值進行比較的 System.Collections.Generic.IEqualityComparer<T>。 // // 類型參數: // TSource: // 輸入序列中的元素的類型。 // // 返回結果: // 一個 System.Collections.Generic.IEnumerable<T>,包含兩個輸入序列中的元素(重復元素除外)。 // // 異常: // System.ArgumentNullException: // first 或 second 為 null。 public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer);
還有一個重載函數,還有一個比較器
那咱們就寫一個比較器唄
public class FishComPare : IEqualityComparer<Fish> { public bool Equals(Fish x, Fish y) { return x.Name == y.Name && x.ID==y.ID; } public int GetHashCode(Fish obj) { return obj.Name.GetHashCode(); } }
然后全部代碼
class Program { static void Main(string[] args) { List<Fish> a = new List<Fish>(); a.Add(new Fish() { Name = "測試1", ID = 0, Message = "" }); a.Add(new Fish() { Name = "測試2", ID = 1, Message = "" }); a.Add(new Fish() { Name = "測試3", ID = 2, Message = "" }); a.Add(new Fish() { Name = "測試4", ID = 3, Message = "" }); List<Fish> b = new List<Fish>(); b.Add(new Fish() { Name = "測試1", ID = 0, Message = "" }); b.Add(new Fish() { Name = "測試3", ID = 5, Message = "" }); b.Add(new Fish() { Name = "測試5", ID = 6, Message = "" }); List<Fish> c = a.Union(b,new FishComPare()).ToList(); //List<Fish> c = a.Intersect(b,,new FishComPare()).ToList(); foreach (var item in c) { Console.WriteLine("Name:{0},ID:{1}", item.Name, item.ID); } Console.ReadLine(); } } public class Fish { public string Name { get; set; } public int ID { get; set; } public string Message { get; set; } } public class FishComPare : IEqualityComparer<Fish> { public bool Equals(Fish x, Fish y) { return x.Name == y.Name && x.ID==y.ID; } public int GetHashCode(Fish obj) { return obj.Name.GetHashCode(); } }
運行
得到我們想要的結果了,同理,交集也是同樣方法
如果我想以Name來比較怎么辦,也就是說 我想把”測試3“相同的當一樣的,不管ID是否相同,那也好辦,我么只需要
public class FishComPare : IEqualityComparer<Fish> { public bool Equals(Fish x, Fish y) { return x.Name == y.Name; } public int GetHashCode(Fish obj) { return obj.Name.GetHashCode(); } }
然后我們繼續求並集,得到如下結果
也就是說 我們可以以一個類中的一個元素來當做比較對象,這種方式要省了很大力氣,雖然遍歷循環也能實現,但是有方便的何不拿來直接用呢
