1. 程式人生 > >.Net Collection Distinct 去重

.Net Collection Distinct 去重

 由於業務場景的需要,海量的資料需要進行處理、組裝,難免會出現冗餘的重複資料。如何處理重複的資料就是一個問題。

簡單的集合中,去重就可以用linq distinct來完成。對於複雜的集合直接使用distinct就會顯得沒那麼有效了。

  • 造資料

構造1M的orderentity,非重複的資料為1M/2.

 1 IList<OrderEntity> sourceList = new List<OrderEntity>();
 2             for (int i = 0; i < 1000000; i++)
 3             {
4 OrderEntity o = new OrderEntity 5 { 6 OrderNo = i % 500000, 7 Amount = 1, 8 Detail = "test" 9 }; 10 sourceList.Add(o); 11 }

方式一:直接distinct

1 var list = sourceList.Distinct().ToList(); 
2 Console.WriteLine(list.Count + " 耗時:" + watch.ElapsedMilliseconds);

 

結果還是1M,對於複雜的集合 distinct直接使用是沒效果的。

方法二:對資料分組

1 var list2 = sourceList.GroupBy(t => new
2             {
3                 t.OrderNo,
4                 t.Amount,
5                 t.Detail
6 
7             }).Select(g => g.First()).ToList();
8 9 Console.WriteLine(list2.Count + " 耗時:" + watch.ElapsedMilliseconds);

結果是500K, 對集合group處理還是有作用的,可惜的是耗時較高。

方法三:推薦 使用Distinct 過載

 1 public class OrderEntityComparer : IEqualityComparer<OrderEntity>
 2     {
 3         public bool Equals(OrderEntity x, OrderEntity y)
 4         {
 5             if (Object.ReferenceEquals(x, y)) return true;
 6             if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
 7                 return false;
 8             return x.OrderNo == y.OrderNo && x.Amount == x.Amount && x.Detail == y.Detail;
 9         }
10 
11         public int GetHashCode(OrderEntity obj)
12         {
13             //Check whether the object is null
14             if (Object.ReferenceEquals(obj, null)) return 0;
15             //Get hash code for the Name field if it is not null.
16             int hashOrderNo = obj.OrderNo.GetHashCode();
17 
18             //Get hash code for the Code field.
19             int hashAmount = obj.Amount.GetHashCode();  
20 
21             int hashDetail = obj.Detail == null ? 0 : obj.Detail.GetHashCode();
22             //Calculate the hash code for the product.
23             return hashOrderNo ^ hashAmount ^ hashDetail;
24         }
25     }
1  var list3 = sourceList.Distinct(new OrderEntityComparer()).ToList();
2 
3 Console.WriteLine(list3.Count + " 耗時:" + watch.ElapsedMilliseconds);

 結果:達到去重目的,耗時也可以接受。