.Net Collection Distinct 去重
阿新 • • 發佈:2018-12-21
由於業務場景的需要,海量的資料需要進行處理、組裝,難免會出現冗餘的重複資料。如何處理重複的資料就是一個問題。
簡單的集合中,去重就可以用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);
結果:達到去重目的,耗時也可以接受。