NET問答: 如何通過 Linq 踢掉 List 中的重複記錄 ?

諮詢區

Prasad

我有一個 Items 類,定義如下:


    class Items
    {
        public int Id { getset; }

        public string Name { getset; }

        public int Code { getset; }

        public decimal Price { getset; }
    }

現在 List<Items> 中包含了重複的數據,比如下面這樣。


1         Item1       IT00001        $100
2         Item2       IT00002        $200
3         Item3       IT00003        $150
1         Item1       IT00001        $100
3         Item3       IT00003        $150

請問我如何通過 linq 的方式剔除重複記錄呢 ?

回答區

Christian Hayter

你的這種情況需要給 Items 一個自定義比較器,參考如下代碼。


class DistinctItemComparer : IEqualityComparer<Item> {

    public bool Equals(Item x, Item y) {
        return x.Id == y.Id &&
            x.Name == y.Name &&
            x.Code == y.Code &&
            x.Price == y.Price;
    }

    public int GetHashCode(Item obj) {
        return obj.Id.GetHashCode() ^
            obj.Name.GetHashCode() ^
            obj.Code.GetHashCode() ^
            obj.Price.GetHashCode();
    }
}

有了這個比較器,後面就方便了。


var distinctItems = items.Distinct(new DistinctItemComparer());

Salah Akbari

我覺得有三種方式可以刪除 List 中的重複記錄。

  • 使用自定義的比較器,就像樓上那哥們說的。

  • 使用 GroupBy,把 Items 的所有屬性名灌到匿名類型上,操作手法如下:


List<Item> a = new List<Item>
{
    new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100},
    new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200},
    new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150},
    new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100},
    new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150},
    new Item {Id = 3, Name = "Item3", Code = "IT00004", Price = 250}
};

var distinctItems = a.GroupBy(c => new { c.Id , c.Name , c.Code , c.Price})
                     .Select(c => c.First()).ToList();

  • 重寫 Equals 和 GetHashCode 方法。

public class Item
{
    public int Id { getset; }
    public string Name { getset; }
    public string Code { getset; }
    public int Price { getset; }

    public override bool Equals(object obj)
    {
        if (!(obj is Item))
            return false;
        Item p = (Item)obj;
        return (p.Id == Id && p.Name == Name && p.Code == Code && p.Price == Price);
    }
    public override int GetHashCode()
    {
        return String.Format("{0}|{1}|{2}|{3}", Id, Name, Code, Price).GetHashCode();
    }
}

然後就可以直接通過 Distinct() 過濾啦。


var distinctItems = a.Distinct();

點評區

我覺得 Salah Akbari 大佬總結的真到位😁😁😁,尤其是通過 GroupBy + Anonymous 的方式, 🐂👃,沒啥好說的,學習了。


本文分享自微信公衆號 - 一線碼農聊技術(dotnetfly)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章