C# Linq中按ShopName移除MaxDiscountOwner重复元素的实现方案问询
问题解答:按店铺去重并保留最高折扣记录
当然可以实现你的需求!核心目标就是对每个店铺仅保留折扣最高的那条MaxDiscountOwner记录,下面给你两种实用的实现方案,还附带性能优化建议:
核心思路
你的原始代码已经完成了排序,但缺少「按店铺去重」的关键步骤。我们可以通过两种方式实现:
- 先按店铺分组,每组内筛选出折扣最高的记录
- 先按店铺+折扣降序排序,再按店铺去重(保留每组第一条即最高折扣)
方案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
相关产品推荐
相关产品推荐

