還在為刪除集合中的相同項而煩惱嗎?


      在項目過程中大家都會遇到這樣的需求,去除相同數據項目。不知道大家做多這樣的需求沒有,把csv數據導入到DB中。要求csv中如果某幾個列相同,這樣的數據就不插入到庫中。
第一個閃現在大家腦海中的方法是不是直接寫個循環,然后一個個去判斷。今天我們來看看另一套方法。利用Distinct方法來進行實現。
      我們來看看這個方法,這個方法來之Enumerable這個靜態類,里面有這樣一個方法
      public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer);
這個方法是一個擴展方法。在形參里面有兩個參數,大家有沒有看到第一個形參中有個this,其實這就是擴展方法。在這里給大家稍微溫習下擴展方法,
擴展方法是編譯器的一種手段。它需要幾個條件
1、在靜態類中

2、是一個靜態的公共的方法

3、第一個形參前要加上一個this


這樣就可以了。你要擴展到哪個類中去,那么第一個參數就是那個類的類型。

我們再來看看第二個參數IEqualityComparer<TSource> comparer是一個IEqualityComparer<TSource>的泛型接口。
我們看看這個泛型接口,這個接口里面只有兩個方法
       bool Equals(T x, T y);
       int GetHashCode(T obj);
我們來看看Equals,從解釋中我們知道。如果兩個對象是相等的就返回true,如果不相等就返回false。

好的,那我們就來構造集合中的Distinct方法需要的條件。
首先我們來實現我們自己的比較類,然后再來實現這個接口。
我們這個類的需求是這樣的。可以自定設定要比較的屬性名,可以是多個也可是是單個。

分析就到這里,接下來我們來看看具體的實現方式
請看代碼:

View Code
 1 /// <summary>
 2     /// 消除集合中的相同的對象
 3     /// </summary>
 4     /// <typeparam name="T"></typeparam>
 5     public class DistinctObj<T> : IEqualityComparer<T>
 6     {
 7         /// <summary>
 8         /// 相同的屬性名集合
 9         /// </summary>
10         private List<string> lstPropertyName = new List<string>();
11 
12         /// <summary>
13         /// 設置屬性集合
14         /// </summary>
15         /// <param name="propertyNameArr">屬性集合數組</param>
16         public void SetCompareProperty(params string[] propertyNameArr) 
17         {
18             lstPropertyName.AddRange(propertyNameArr);
19         }
20 
21         #region IEqualityComparer<T> Member
22 
23         public bool Equals(T x, T y)
24         {
25             Type t = typeof(T);
26             
27             List<object> lstProperty1Value = new List<object>();
28             List<object> lstProperty2Value = new List<object>();
29 
30             foreach (string propertyName in this.lstPropertyName)
31             {
32                 object value1 = t.GetProperty(propertyName).GetValue(x, null);
33                 object value2 = t.GetProperty(propertyName).GetValue(y, null);
34 
35 
36                 // 同時為空的時候,在比較的時候會報錯,這里給其自動設置默認值
37                 string guid = Guid.NewGuid().ToString();
38                 if (value1 == null) 
39                 {
40                     value1 = guid;
41                 }
42 
43                 if (value2 == null) 
44                 {
45                     value2 = guid;
46                 }
47 
48                 lstProperty1Value.Add(value1);
49                 lstProperty2Value.Add(value2);
50             }
51 
52             bool isTrue = false;
53 
54             int equalCount = 0;
55 
56             for (int index = 0; index < lstProperty1Value.Count; index++)
57             {
58                 if (lstProperty1Value[index].Equals(lstProperty2Value[index])) 
59                 {
60                     equalCount++;
61                 }
62             }
63 
64             if (equalCount == lstProperty2Value.Count)
65             {
66                 isTrue = true;
67             }
68 
69             return isTrue;
70         }
71 
72         public int GetHashCode(T obj)
73         {
74             return 0;
75         }
76 
77         #endregion
78     }

具體代碼就如上面所示,代碼很簡單,就是接受了要比較的對象名。然后比較這個對象的是否相等。

如果大家有啥不明白的地方就回復下,我第一時間給大家解釋。

接下來,我們來看看調用方式和顯示結果。

測試代碼如下:

View Code
 1 public class Student {
 2 
 3             public string StuNo { get; set; }
 4 
 5             public string StuName { get; set; }
 6 
 7             public string StuTel { get; set; }
 8 
 9             public Student(string no,string name,string tel)
10             {
11                 this.StuNo = no;
12                 this.StuName = name;
13                 this.StuTel = tel;
14             }
15         }
16 
17 
18 List<Student> lstStu = new List<Student>(){
19                 new Student("0001","","137"),
20                 new Student("0001","","138"),
21                 new Student("0002","","137"),
22                 new Student("0001","","138"),
23                 new Student("0002","","137"),
24                 new Student("0003","","137"),
25                 new Student("0001","","137"),
26                 new Student("0008","","136"),
27                 new Student("0008","","137")
28             };
29 
30             Console.WriteLine("未刪除重復前..............");
31             foreach (Student student in lstStu)
32             {
33                 Console.WriteLine("No " + student.StuNo + " Name " + student.StuName + "  Tel " + student.StuTel);
34             }
35 
36             DistinctObj<Student> distinct = new DistinctObj<Student>();
37             distinct.SetCompareProperty(new string[] { "StuNo", "StuTel" });
38 
39             List<Student> lst = lstStu.Distinct(distinct).ToList();
40             Console.WriteLine("刪除重復后..............");
41             foreach (Student student in lst)
42             {
43                 Console.WriteLine("No " + student.StuNo + " Name " + student.StuName + "  Tel " + student.StuTel);
44             }
45 
46             Console.Read();

 

結果如下:

不好意思啊。我這里是日文的操作系統。那幾個中文字顯示的不到位啊。不過不影響大家看效果啊。

廣納各位的意見。歡迎大家拍磚。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM