【C#】list 去重(轉載)

來源:互聯網
上載者:User

標籤:def   this   重複記錄   mon   div   obj   console   turn   c#   

Enumerable.Distinct 方法 是常用的LINQ擴充方法,屬於System.Linq的Enumerable方法,可用於去除數組、集合中的重複元素,還可以自訂去重的規則。

有兩個重載方法:

        //        // 摘要:         //     通過使用預設的相等比較子對值進行比較返回序列中的非重複元素。        //        // 參數:         //   source:        //     要從中移除重複元素的序列。        //        // 型別參數:         //   TSource:        //     source 中的元素的類型。        //        // 返回結果:         //     一個 System.Collections.Generic.IEnumerable<T>,包含源序列中的非重複元素。        //        // 異常:         //   System.ArgumentNullException:        //     source 為 null。        public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source);        //        // 摘要:         //     通過使用指定的 System.Collections.Generic.IEqualityComparer<T> 對值進行比較返回序列中的非重複元素。        //        // 參數:         //   source:        //     要從中移除重複元素的序列。        //        //   comparer:        //     用於比較值的 System.Collections.Generic.IEqualityComparer<T>。        //        // 型別參數:         //   TSource:        //     source 中的元素的類型。        //        // 返回結果:         //     一個 System.Collections.Generic.IEnumerable<T>,包含源序列中的非重複元素。        //        // 異常:         //   System.ArgumentNullException:        //     source 為 null。        public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer);    

第一個方法不帶參數,第二個方法需要傳一個System.Collections.Generic.IEqualityComparer<T>的實現對象

1.實值型別元素集合去重

List<int> list = new List<int> { 1, 1, 2, 2, 3, 4, 5, 5 };list.Distinct().ToList().ForEach(s => Console.WriteLine(s));

執行結果是:1 2 3 4 5

2.參考型別元素集合去重

首先自訂一個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>        /// 方便輸出,重寫ToString方法        /// </summary>        /// <returns></returns>        public override string ToString()        {            return string.Format("{0}\t{1}\t{2}", this.Name, this.Id, this.Hobby);        }    }

使用不到參數的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()));   

執行結果:

可見,並沒有去除重複的記錄。

不帶comparer參數的Distinct方法是使用的IEqualityComparer介面的預設比較子進行比較的,對於參考型別,預設比較子比較的是其引用地址,程式中集合裡的每一個元素都是個新的執行個體,引用地址都是不同的,所以不會被作為重複記錄刪除掉。

因此,我們考慮使用第二個重載方法。

建立一個類,實現IEqualityComparer介面。注意GetHashCode方法的實現,只有HashCode相同才會去比較

    public class Compare:IEqualityComparer<Student>    {        public bool Equals(Student x,Student y)        {            return x.Id == y.Id;//可以自訂去重規則,此處將Id相同的就作為重複記錄,不管學生的愛好是什麼        }        public int GetHashCode(Student obj)        {            return obj.Id.GetHashCode();        }    }

然後調用

list.Distinct(new Compare()).ToList().ForEach(s => Console.WriteLine(s.ToString()));

執行結果:

我們按照Id去給這個集合去重成功!

3.如何編寫一個具有擴充性的去重方法

    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擴充方法        /// </summary>        /// <typeparam name="T">要去重的對象類</typeparam>        /// <typeparam name="C">自訂去重的欄位類型</typeparam>        /// <param name="source">要去重的對象</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));        }    }

調用:

list.MyDistinct(s=>s.Id).ToList().ForEach(s => Console.WriteLine(s.ToString()));

用到了泛型、委託、擴充方法等知識點。可以用於任何集合的各種去重情境

 

轉載來源:https://www.cnblogs.com/Robert-go-go/p/5399198.html

【C#】list 去重(轉載)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.