You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Linq中按ShopName移除MaxDiscountOwner重复元素的实现方案问询

问题解答:按店铺去重并保留最高折扣记录

当然可以实现你的需求!核心目标就是对每个店铺仅保留折扣最高的那条MaxDiscountOwner记录,下面给你两种实用的实现方案,还附带性能优化建议:

核心思路

你的原始代码已经完成了排序,但缺少「按店铺去重」的关键步骤。我们可以通过两种方式实现:

  1. 先按店铺分组,每组内筛选出折扣最高的记录
  2. 先按店铺+折扣降序排序,再按店铺去重(保留每组第一条即最高折扣)

方案1:使用GroupBy(兼容所有.NET版本)

这种方式逻辑最直观,适合所有.NET版本(包括.NET Framework):

static IEnumerable<MaxDiscountOwner> GetMaxDiscountPerShop(IEnumerable<Supplier> supplierList, IEnumerable<SupplierDiscount> supplierDiscountList)
{
    // 先把供应商列表转成字典,避免重复遍历查询,大幅提升性能
    var supplierLookup = supplierList.ToDictionary(supplier => supplier.Id);

    return supplierDiscountList
        // 第一步:按店铺名称分组
        .GroupBy(discount => discount.ShopName)
        // 第二步:每组内按折扣降序排序,取第一条(即该店铺最高折扣)
        .Select(group => group.OrderByDescending(d => d.Discount).First())
        // 第三步:构造MaxDiscountOwner对象,用字典快速查找供应商
        .Select(discount => new MaxDiscountOwner
        {
            ShopName = discount.ShopName,
            Discount = discount.Discount,
            Owner = supplierLookup.TryGetValue(discount.SupplierId, out var supplier) ? supplier : null
        })
        // 可选:最终按折扣降序排序(如果需要)
        .OrderByDescending(item => item.Discount);
}

关键优化点:

  • 把supplierList转成Dictionary<int, Supplier>,原来的Where+FirstOrDefault每次都会遍历整个供应商列表,字典查找是O(1)操作,数据量大时性能提升非常明显。
  • 分组后直接取每组最高折扣,逻辑清晰易懂。

方案2:使用DistinctBy(.NET 6+ 专属简洁写法)

如果你使用的是.NET 6或更高版本,可以利用LINQ新增的DistinctBy方法,代码更简洁:

static IEnumerable<MaxDiscountOwner> GetMaxDiscountPerShop(IEnumerable<Supplier> supplierList, IEnumerable<SupplierDiscount> supplierDiscountList)
{
    var supplierLookup = supplierList.ToDictionary(supplier => supplier.Id);

    return supplierDiscountList
        // 第一步:先按店铺名称排序,再按折扣降序排序,确保同店铺最高折扣排在最前面
        .OrderBy(d => d.ShopName)
        .ThenByDescending(d => d.Discount)
        // 第二步:按店铺名称去重,只保留每组第一条(即最高折扣记录)
        .DistinctBy(d => d.ShopName)
        // 第三步:构造目标对象
        .Select(discount => new MaxDiscountOwner
        {
            ShopName = discount.ShopName,
            Discount = discount.Discount,
            Owner = supplierLookup.TryGetValue(discount.SupplierId, out var supplier) ? supplier : null
        })
        // 可选:最终按折扣降序排序
        .OrderByDescending(item => item.Discount);
}

说明:

DistinctBy会根据指定的键(这里是ShopName)去重,只保留第一个出现的元素。因为我们已经先按折扣降序排序,所以第一个出现的就是该店铺的最高折扣记录。


验证结果

两种方案最终都会输出你预期的结果:每个店铺仅保留一条最高折扣的MaxDiscountOwner记录,且可以按折扣从高到低排序。

内容的提问来源于stack exchange,提问作者anon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 16:49:04