iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
0

LINQ的Set method有很多,包含前幾天提到的All / Any、Contains、Distinct等,還有比較不常使用到的Union、Except和Intersect這種再高中學數學的聯集、差集與交集。今天會提一些情境可以考慮使用這些大家比較少用的Set method。

  1. Union:計算兩個集合聯集

    var numbers1 = new List<int>() {1, 2, 3};
    var numbers2 = new List<int>() {2, 3, 4};
    numbers1.Union(numbers2).ToList(); // 輸出{1, 2, 3, 4}
    
  2. Intersect:計算兩集合的交集

    var numbers1 = new List<int>() {1, 2, 3};
    var numbers2 = new List<int>() {2, 3, 4};
    numbers1.Intersect(numbers2).ToList(); // 輸出{2, 3}
    
  3. Except:計算兩個集合的差集

    var numbers1 = new List<int>() {1, 2, 3};
    var numbers2 = new List<int>() {2, 3, 4};
    numbers1.Except(numbers2).ToList(); // 輸出{1, 2, 3, 4}
    

假設我們再設計一個商品競標系統,有個類別負責儲存每個商品的即時價格。_current儲存的當前商品資訊,當有新的資訊時,系統則會透過UpdateGoods來更新即時商品價格。

public class GoodsCache
{
    private List<Goods> _goods = new List<Goods>();

    public void UpdateGoods(List<Goods> latestGoods)
    {
        _goods = latestGoods;
    }
}

public class Goods
{
    public int Id { get; set; }

    public decimal Price { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is Goods goods)
        {
            return goods.Id == Id;
        }

        return false;
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
}

當我們想知道哪些哪些商品是新上架或下架時,可以透過Except來簡單比較出新的商品或下架商品。拿最新商品集合與上一次的舊集合做差集,就能比較出這次新上架的商品集合。反之亦然,如果拿舊商品集合與新商品集合做差集,則能得出已經下架的商品。

New = latestGoods.Except(Current).ToList();
Delete = Current.Except(latestGoods).ToList();

另外我們同時也時常會需要把已經在架上商品價格更新,並提示使用者這項商品的價格已經變了。所以我們會需要哪些商品是有價格更新的。透過Intersect能輕鬆找出哪些是還在架上的商品

Goods = latestGoods.Intersect(Current).ToList();

但是這其中包含了價格不變與價格有變的兩種情況,為了顯示目的我們只需要那些價格有變的商品集合,我們可以透過自訂IEqualityComparer來幫助我們找到那些價格有變的商品。

public class GoodsPriceCompare : IEqualityComparer<Goods>
{
    public bool Equals(Goods goods1, Goods goods2)
    {
        return goods1.Id == goods2.Id && goods1.Price != goods2.Price;
    }

    public int GetHashCode(Goods goods)
    {
        return goods.GetHashCode();
    }
}

透過自訂相等的邏輯再加上intersect,我們便能更快的過濾出那些價格有變的商品。

PriceChange = latestGoods.Intersect(Current, new GoodsPriceCompare()).ToList();

鐵人賽也過去一半了,我們聊了許多關於LINQ方法的用法與一些可以使用的情境,但是還是有一些好用的LINQ方法沒有介紹到。未來如果有機會,可能會在透過一些比較實際的例子來介紹給大家。


上一篇
Day 14 一些Paging LINQ的使用情境
下一篇
Day 16 當錯誤發生時(上)
系列文
在Kata中尋找Clean Code是否搞錯了什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言