【C#】list 去重(轉載)

来源:https://www.cnblogs.com/hao-1234-1234/archive/2018/04/16/8855218.html
-Advertisement-
Play Games

Enumerable.Distinct 方法 是常用的LINQ擴展方法,屬於System.Linq的Enumerable方法,可用於去除數組、集合中的重覆元素,還可以自定義去重的規則。 有兩個重載方法: // // 摘要: // 通過使用預設的相等比較器對值進行比較返回序列中的非重覆元素。 // / ...


 

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 面向對象的組合用法 軟體重用的重要方式除了繼承之外還有另外一種方式,即:組合 組合指的是,在一個類中以另外一個類的對象作為數據屬性,稱為類的組合。 ...
  • 概述 UWP Community Toolkit 中有一個 Animations 的集合,它們可以幫助開發者實現很多的動畫,本篇我們先來看一下 Animations 的功能都有哪些,再後面會針對每一種 Animations 做詳細的代碼分析。 Animations 集合涵蓋了很多種類的動畫,我們先來 ...
  • 這篇博客的標題用了一個疑問句,源於我們公司的代碼評審,深刻的討論了單例模式的使用場景及其與靜態方法來說有何不同,這次討論確實讓我真正的理解了單例模式的使用,雖然說理解還一定全面,但必須作為一個認知的提升。告訴了我自己,對於編程,不懂的太多,原理性的東西還需要持續的學習。 進入正文,我們來討論一下,什 ...
  • 主題 之前簡單介紹了Asp.net core 的初步的使用,本篇我打算給大家介紹一下Identity的架構,讓大家對Identity有一個總體的理解和認識。 簡介 博客原文歡迎訪問我的博客網站,地址是:[深入理解Aspnet Core之Identity(4) ] : https://www.blue ...
  • 使用Json.Net可以把一個Json字元串轉換成一個JObject對象,如果有已知強類型,如果有已知對應的強類型,可以直接轉成對應的類型。但如果沒有,要訪問Json裡面對應的數據的時候,就顯得比較麻煩。我們可以藉助DynamicObject來訪問對應的屬性。 ...
  • 本文的概念內容來自深入淺出設計模式一書 現實世界中的適配器(模式) 我帶著一個國標插頭的筆記本電腦, 來到歐洲, 想插入到歐洲標準的牆壁插座裡面, 就需要用中間這個電源適配器. 面向對象的適配器 你有個老系統, 現在來了個新供應商的類, 但是它們的介面不同, 如何使用這個新供應商的類呢? 首先, 我 ...
  • WFP 的 Generic.xaml ,App.xaml 等中的資源會被調用 Freezable. 在後臺對該資源進行修改等操作會被提示.資源為密封對象. 如果,確定需要在後臺對資源進行修改. 則需要在資源中加入x:Shared="False"聲明 則不對該資源執行 Freezable() ...
  • 第一種-文章出處 > www.miniui.com/demo/listbox/moveitems.html <body> <h1>兩個ListBox之間選擇移動項 </h1> <input type="button" value="Save" onclick="saveData()" style=" ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...