【C#】详解使用Enumerable.Distinct方法去重
Enumerable.Distinct 方法 是常用的LINQ擴(kuò)展方法,屬于System.Linq的Enumerable方法,可用于去除數(shù)組、集合中的重復(fù)元素,還可以自定義去重的規(guī)則。
有兩個(gè)重載方法:
//// 摘要: // 通過(guò)使用默認(rèn)的相等比較器對(duì)值進(jìn)行比較返回序列中的非重復(fù)元素。//// 參數(shù): // source:// 要從中移除重復(fù)元素的序列。//// 類型參數(shù): // TSource:// source 中的元素的類型。//// 返回結(jié)果: // 一個(gè) System.Collections.Generic.IEnumerable<T>,包含源序列中的非重復(fù)元素。//// 異常: // System.ArgumentNullException:// source 為 null。public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source);//// 摘要: // 通過(guò)使用指定的 System.Collections.Generic.IEqualityComparer<T> 對(duì)值進(jìn)行比較返回序列中的非重復(fù)元素。//// 參數(shù): // source:// 要從中移除重復(fù)元素的序列。//// comparer:// 用于比較值的 System.Collections.Generic.IEqualityComparer<T>。//// 類型參數(shù): // TSource:// source 中的元素的類型。//// 返回結(jié)果: // 一個(gè) System.Collections.Generic.IEnumerable<T>,包含源序列中的非重復(fù)元素。//// 異常: // System.ArgumentNullException:// source 為 null。public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer);第一個(gè)方法不帶參數(shù),第二個(gè)方法需要傳一個(gè)System.Collections.Generic.IEqualityComparer<T>的實(shí)現(xiàn)對(duì)象
1.值類型元素集合去重
List<int> list = new List<int> { 1, 1, 2, 2, 3, 4, 5, 5 }; list.Distinct().ToList().ForEach(s => Console.WriteLine(s));執(zhí)行結(jié)果是:1 2 3 4 5
2.引用類型元素集合去重
首先自定義一個(gè)Student類
public class Student{public string Name { get; private set; }public int Id { get; private set; }public string Hobby { get; private set; }public Student(string name, int id, string hobby){this.Name = name;this.Id = id;this.Hobby = hobby;}/// <summary>/// 方便輸出,重寫(xiě)ToString方法/// </summary>/// <returns></returns>public override string ToString(){return string.Format("{0}\t{1}\t{2}", this.Name, this.Id, this.Hobby);}} View Code使用不到參數(shù)的Distinct方法去重
List<Student> list = new List<Student>() { new Student("James",1,"Basketball"),new Student("James",1,"Basketball"),new Student("Kobe",2,"Basketball"),new Student("Curry",3,"Football"),new Student("Curry",3,"Yoga")};list.Distinct().ToList().ForEach(s => Console.WriteLine(s.ToString()));執(zhí)行結(jié)果:
可見(jiàn),并沒(méi)有去除重復(fù)的記錄。
不帶comparer參數(shù)的Distinct方法是使用的IEqualityComparer接口的默認(rèn)比較器進(jìn)行比較的,對(duì)于引用類型,默認(rèn)比較器比較的是其引用地址,程序中集合里的每一個(gè)元素都是個(gè)新的實(shí)例,引用地址都是不同的,所以不會(huì)被作為重復(fù)記錄刪除掉。
因此,我們考慮使用第二個(gè)重載方法。
新建一個(gè)類,實(shí)現(xiàn)IEqualityComparer接口。注意GetHashCode方法的實(shí)現(xiàn),只有HashCode相同才會(huì)去比較
public class Compare:IEqualityComparer<Student>{public bool Equals(Student x,Student y){return x.Id == y.Id;//可以自定義去重規(guī)則,此處將Id相同的就作為重復(fù)記錄,不管學(xué)生的愛(ài)好是什么 }public int GetHashCode(Student obj){return obj.Id.GetHashCode();}}然后調(diào)用
list.Distinct(new Compare()).ToList().ForEach(s => Console.WriteLine(s.ToString()));執(zhí)行結(jié)果:
我們按照Id去給這個(gè)集合去重成功!
3.如何編寫(xiě)一個(gè)具有擴(kuò)展性的去重方法
public class Compare<T, C> : IEqualityComparer<T>{private Func<T, C> _getField;public Compare(Func<T, C> getfield){this._getField = getfield;}public bool Equals(T x, T y){return EqualityComparer<C>.Default.Equals(_getField(x), _getField(y));}public int GetHashCode(T obj){return EqualityComparer<C>.Default.GetHashCode(this._getField(obj));}}public static class CommonHelper{/// <summary>/// 自定義Distinct擴(kuò)展方法/// </summary>/// <typeparam name="T">要去重的對(duì)象類</typeparam>/// <typeparam name="C">自定義去重的字段類型</typeparam>/// <param name="source">要去重的對(duì)象</param>/// <param name="getfield">獲取自定義去重字段的委托</param>/// <returns></returns>public static IEnumerable<T> MyDistinct<T, C>(this IEnumerable<T> source, Func<T, C> getfield){return source.Distinct(new Compare<T, C>(getfield));}} View Code調(diào)用:
list.MyDistinct(s=>s.Id).ToList().ForEach(s => Console.WriteLine(s.ToString()));用到了泛型、委托、擴(kuò)展方法等知識(shí)點(diǎn)。可以用于任何集合的各種去重場(chǎng)景
轉(zhuǎn)載于:https://www.cnblogs.com/Robert-go-go/p/5399198.html
總結(jié)
以上是生活随笔為你收集整理的【C#】详解使用Enumerable.Distinct方法去重的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 基于虎书实现LALR(1)分析并生成GL
- 下一篇: TEMPO研究第一年影像学数据: 骨侵蚀