首頁 » C#開發 » [C# LINQ] List Distinct搭配IEqualityComparer實現規則自定義

[C# LINQ] List Distinct搭配IEqualityComparer實現規則自定義

作者:

分類:

前言

C# LINQ提供很多方便的List<T>查詢方法,如果需要查詢列表中沒有重複的項目時會呼叫Distinct(),這時.NET會使用預設的比較器去做查詢,也就是用物件的HashCode做比較

假設T是int,可以預期結果是1, 2, 3, 4

List<int> numList = new List() { 1, 2, 2, 3, 4 }

var listDistinct = numList.Distinct();
//OUTPUT: 1, 2, 3, 4

如果T是一個物件(object)呢?

class MyObj
{
    public int Num { get; set; } = 0;
    public string Text { get; set; } = string.Empty;
}

實作IEqualityComparer

只需要實作IEqualityComparer<T>就可以自訂比較的規則,如果只要比較Text屬性,那就把Num拿掉即可。

class MyObjEqualityComparer : IEqualityComparer<MyObj>
{
    public bool Equals(MyObj obj1, MyObj obj2)
    {
        if (ReferenceEquals(obj1, obj2))
            return true;

        if (obj1 is null || obj2 is null)
            return false;

        return obj1.Num == obj2.Num
            && obj1.Text == obj2.Text;
    }

    public int GetHashCode(MyObj obj) => obj.Num ^ obj.Text.GetHashCode();
}

使用時,只需要將Comparer傳給Distinct即可。超級方便。

IEnumerable<MyObj> noduplicates =
    myObjList.Distinct(new MyObjEqualityComparer());

結語

在此之前,自己都先Select要比較的項目,Distinct之後再去一個一個Find或是First,但用多了實在很麻煩,而且維護上邏輯切換更是一大問題。

好在C#.NET有提供IEqualityComparer<T>,只要按規則走就能非常上手,現在只要抽換Comparer就能做到邏輯切換的功能

參考資料

「cian」的個人頭像

留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *