簡單例子-代碼編寫:
首先創建實體:
#region 公司 public class Company { /// <summary> /// ID /// </summary> public int ID { get; set; } /// <summary> /// 公司名稱 /// </summary> public string CompanyName { get; set; } /// <summary> /// 地址 /// </summary> public string Address { get; set; } } #endregion
實際操作:
static void Main(string[] args){
List<Company> companys = new List<Company>();//公司實體Company,字段-公司名稱,公司地址,電話 companys.Add(new Company() { ID = 1, CompanyName = "龍龍股份有限公司", Address = "固戍北辰路666號" }); companys.Add(new Company() { ID = 2, CompanyName = "龍龍股份有限公司", Address = "固戍放飛路三號" });//最后結果,重復項,此條數據刪除 companys.Add(new Company() { ID = 3, CompanyName = "軍軍股份有限公司", Address = "固戍路甲八號" }); #region 方式一 //方式一:Lambda表達式去重 List<Company> companyList1 = companys.Where((x, i) => companys.FindIndex(z => z.CompanyName == x.CompanyName) == i).ToList(); #endregion #region 方式二 //方式二:List中的元素實現IEquatabe接口,並提供Equals方法和GetHashCode方法。 List<Company> companyList2 = companys.Distinct(new Dis()).ToList(); #endregion #region 方式三 //方式三:通過循環方式去重 List<Company> companyList3 = new List<Company>(); foreach (Company company in companys) { var isExists = companyList3.Exists(x => x.CompanyName == company.CompanyName);//是否存在相同數據 if (isExists == false) { companyList3.Add(company); } } #endregion
//對比三種方式獲取的數據就會知道一樣的,第二條重復數據沒有了。
} #region Distinct篩選對比去重 /// <summary> /// Distinct篩選對比去重 /// </summary> public class Dis : IEqualityComparer<Company> { public bool Equals(Company x, Company y) { return x.CompanyName == y.CompanyName;//根據篩選的要求來判斷 } public int GetHashCode(Company obj) { if (obj != null) { return obj.CompanyName.GetHashCode();//根據篩選的要求來判斷 } return 0; } } #endregion
提醒:IEqualityComparer<TSource> 定義了兩個方法,一個是Equals,一個是GetHashCode。這里我查找參考資料發現,進行比較時,默認先通過GetHashCode對兩個元素進行比較,如果HashCode不同,則認為兩個元素不同,如果相同則再通過Equals方法比較。所以這里我不能直接將Company對象GetHashCode處理,而是先轉換成了字符串再GetHashCode。通過這個重載方法,我們就可以到達目的了;
方法二中Distinct 擴展:
1.Distinct方法不加參數的話,去重的規則是比較對象集合中對象的引用是否相同,如果相同,則去重,否則不去重。
2.Distinct方法加參數的話,我們需建一個類繼承IEqualityComparer接口必須實現Equals和GetHashCode方法,然后在類里面根據自己的需求條件來寫相關的判斷。我們要向靈活可以優化封裝一下。
代碼如下:
#region 封裝Distinct去重 /// <summary> /// 封裝Distinct去重 /// </summary> /// <typeparam name="T"></typeparam> public class LambdaComparer<T> : IEqualityComparer<T> { private readonly Func<T, T, bool> _lambdaEquals;//相等 private readonly Func<T, int> _lambdaHash;//哈希 public LambdaComparer(Func<T, T, bool> lambdaEquals) : this(lambdaEquals, EqualityComparer<T>.Default.GetHashCode) { } public LambdaComparer(Func<T, T, bool> lambdaEquals, Func<T, int> lambdaHash) { if (lambdaEquals == null) throw new ArgumentNullException("lambdaEquals");//引發異常名稱 if (lambdaHash == null) throw new ArgumentNullException("lambdaHash");//引發異常名稱 _lambdaEquals = lambdaEquals; _lambdaHash = lambdaHash; } /// <summary> /// 是否相等 /// </summary> /// <param name="x">X</param> /// <param name="y">Y</param> /// <returns></returns> public bool Equals(T x, T y) { return _lambdaEquals(x, y); } /// <summary> /// 獲取哈希碼 /// </summary> /// <param name="obj">obj</param> /// <returns></returns> public int GetHashCode(T obj) { return _lambdaHash(obj); } } #endregion
上面很好的利用了泛型委托的方式。下面我們想怎么比較就怎么比較了:
List<Company> companyList2 = companys.Distinct(new LambdaComparer<Company>((x, y) => x.CompanyName == y.CompanyName, obj => obj.ToString().GetHashCode())).ToList(); //List<Company> companyList2 = companys.Distinct(new LambdaComparer<Company>((a, b) => a.CompanyName == b.CompanyName && a.ID == b.ID, obj => obj.ToString().GetHashCode())).ToList();//可多個條件
Distinct參考資料: