1. 程式人生 > >數據去重

數據去重

描述 ima pre 數據去重 拓展 mage ring img http

平時,我們將c#中的Distinct大多用於對數組去重,一般數組為基礎的數據類型,例如 int,string.也可以用於對象去重,我們看看C#對Distinct方法的定義:
技術分享圖片


有重載,第一個參數都加了this,是拓展方法,有關拓展方法,請百度了解。
下面我們來研究下Distinct的對象去重,假設我們現在有一個People類:

 public class People
    {
        public int ID { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        public
string Name { get; set; } /// <summary> /// 所屬省份 /// </summary> public string Province { get; set; } /// <summary> /// 年齡 /// </summary> public int Age { get; set; } public override string ToString() { return
string.Format("ID:{0} Name:{1} Province:{2} Age:{3}", ID, Name, Province, Age); } }

我們聲明一個ListPeole對象集合:

People p = new People() { ID = 100, Name = "liu", Province = "廣東", Age = 100 };
            People p1 = p;
            People p2 = p1;
            IEnumerable<People> ListPeople = new
List<People>() { p, p1, p2, new People(){ID=0,Name="li",Province="湖北",Age=20}, new People(){ID=0,Name="li",Province="湖北",Age=20}, new People(){ID=1,Name="li",Province="湖北",Age=20}, new People(){ID=1,Name="li",Province="湖南",Age=20}, new People(){ID=2,Name="li",Province="湖北",Age=20}, new People(){ID=3,Name="li",Province="湖南",Age=21}, new People(){ID=4,Name="li",Province="湖北",Age=22}, };

我們來對ListPeople使用Distinct方法,不帶任何參數,運行結果如下:
技術分享圖片
可以看到,Distinct方法沒有帶參數的話,將對象集合中p,p1,p2進行去重,而對於對象的成員值是一樣的不同對象沒有去重,說明Distinct方法不加參數的話,去重的規則是比較對象集合中對象的引用是否相同,如果相同,則去重,否則不去重。
現在我們有個需求,對於ID相同的People,我們算做同一個人,要輸出集合中不重復的人(對於ID相同的隨便輸出一個即可),這時,我們用到了Distinct的第二個方法,方法要求傳入的參數是IEqualityComparer類型,繼承一個泛型接口,我們加入如下代碼:

 public class PeopleCompareByID : IEqualityComparer<People>
    {
        public bool Equals(People x, People y)
        {
            if (x == null || y == null)
                return false;
            if (x.ID == y.ID)
                return true;
            else
                return false;
        }

        public int GetHashCode(People obj)
        {
            if (obj == null)
                return 0;
            else
                return obj.ID.GetHashCode();
        }
    }

繼承IEqualityComparer接口必須實現Equals和GetHashCode方法。
我們比較的時候,傳入一個PeopleCompareByID 的實體即可:

ListPeople.Distinct(new PeopleCompareByID()).ToList().ForEach(x => Console.WriteLine(x));

運行結果如下:
技術分享圖片
達到了我們以ID去重的效果。
現在需求又變,ID和省份相同的算同一個人,要輸出人的信息(相同的隨便輸出一個即可),這個時候,我們看到ID=0和Province=”湖北”的存在重復,要將其去重,我們再來一個類,還是繼承自IEqualityComparer:

 public class PeopleCompareByIDAndProvince : IEqualityComparer<People>
    {
        public bool Equals(People x, People y)
        {
            if (x == null || y == null)
                return false;
            if (x.ID == y.ID&&x.Province==y.Province)
                return true;
            else
                return false;
        }

        public int GetHashCode(People obj)
        {
            if (obj == null)
                return 0;
            else
                return obj.ID.GetHashCode()^obj.Province.GetHashCode();
        }
    }

同樣,使用Distinct方法的時候,傳入PeopleCompareByIDAndProvince 的實例:

ListPeople.Distinct(new PeopleCompareByIDAndProvince()).ToList().ForEach(x => Console.WriteLine(x));

運行後的結果如下:
技術分享圖片
達到了我們想要的效果。
以後遇到以三個或者四個甚至更多的對象成員來決定對象是否重復的去重問題時,可以采用這種方法。
以上為個人拙見。

數據去重