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

如何用LINQ对已分组排序的外层数组内层按价格降序排序

Go LINQ 分组后内层数组排序(保持外层顺序)

需求说明

已通过LINQ完成商品按shopId分组,且外层分组已按组内最高商品价格降序排列完成。现需在不改变外层分组顺序的前提下,将每个分组内的商品数组按price字段降序排序。

结构体定义

// 商品结构体
type product struct {
    name   string
    price  int64
    shopId int64
}

// 分组结构体
type oneGroup struct {
    shopId   int64
    products []*product
}

// 最终输出的分组数组
var groupOut []oneGroup

原分组排序代码(已完成外层排序)

products := make([]*product, 0, 20)
products = append(products, &product{name: "product66", price: 6666, shopId: 100})
products = append(products, &product{name: "product11", price: 1111, shopId: 100})
products = append(products, &product{name: "product44", price: 4444, shopId: 100})

products = append(products, &product{name: "product22", price: 2222, shopId: 200})
products = append(products, &product{name: "product77", price: 9999, shopId: 200})
products = append(products, &product{name: "product00", price: 0, shopId: 200})

products = append(products, &product{name: "product33", price: 3333, shopId: 300})
products = append(products, &product{name: "product88", price: 8888, shopId: 300})
products = append(products, &product{name: "product55", price: 5555, shopId: 300})

products = append(products, &product{name: "product99", price: 7777, shopId: 400})

var query []linq.Group

// 按shopId分组,再按组内最高价格降序排列外层分组
linq.From(products).GroupByT(
    func(p *product) int64 { return p.shopId }, // 分组键:shopId
    func(p *product) *product { return p },     // 分组元素:商品对象
).OrderByDescendingT(
    func(g linq.Group) int64 {
        // 获取组内商品的最高价格作为排序依据
        return linq.From(g.Group).Select(
            func(x interface{}) interface{} { return x.(*product).price },
        ).Max().(int64)
    },
).ToSlice(&query)

解决方案

方式1:转换为oneGroup时处理内层排序

遍历已排序的外层分组,对每个分组内的商品数组单独降序排序,再封装为oneGroup类型:

// 初始化结果数组
groupOut = make([]oneGroup, 0, len(query))
for _, group := range query {
    // 提取当前分组的所有商品
    prods := make([]*product, 0, len(group.Group))
    for _, item := range group.Group {
        prods = append(prods, item.(*product))
    }
    // 对商品按price降序排序
    sort.Slice(prods, func(i, j int) bool {
        return prods[i].price > prods[j].price
    })
    // 添加到结果数组
    groupOut = append(groupOut, oneGroup{
        shopId:   group.Key.(int64),
        products: prods,
    })
}

方式2:LINQ链式调用中完成内层排序

直接在LINQ的链式调用中加入SelectT操作,完成分组到oneGroup的转换及内层排序,代码更连贯:

// 直接通过LINQ链式调用完成所有逻辑
linq.From(products).GroupByT(
    func(p *product) int64 { return p.shopId },
    func(p *product) *product { return p },
).OrderByDescendingT(
    func(g linq.Group) int64 {
        return linq.From(g.Group).Select(
            func(x interface{}) interface{} { return x.(*product).price },
        ).Max().(int64)
    },
).SelectT(
    func(g linq.Group) oneGroup {
        prods := make([]*product, 0, len(g.Group))
        for _, item := range g.Group {
            prods = append(prods, item.(*product))
        }
        // 内层商品降序排序
        sort.Slice(prods, func(i, j int) bool {
            return prods[i].price > prods[j].price
        })
        return oneGroup{
            shopId:   g.Key.(int64),
            products: prods,
        }
    },
).ToSlice(&groupOut)

说明

两种方式均不会改变外层分组的原有顺序,仅对每个分组内部的商品数组进行排序。方式2将所有逻辑整合到LINQ链式调用中,代码更简洁。

内容的提问来源于stack exchange,提问作者王建森

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 10:14:56