Go 分组 & 排序

func (r *MultiMarketOverviewService) GetMultiMarketSummaryPriceBandDistributionDataTable(ctx context.Context, req insight.MultiMarketSummaryPriceBandDistributionDataTableReq) response.Response {
    rpcReq := &multi_market_overview.MultiMarketSummaryPriceBandDistributionDataTableReq{}
    copier.Copy(rpcReq, &req)

    rpcResp, err := caller.CompassInsightClient.GetMultiMarketSummaryPriceBandDistributionDataTable(ctx, rpcReq)

    if err != nil {
        return response.JSONSt(define.StRPCErr)
    }

    data := rpcResp.Data
    // 根据 Dimention 分组,按照价格带排序
    sortDataTable(&data)

    return response.JSONData(data)
}

func sortDataTable(data **multi_market_overview.MultiMarketSummaryPriceBandDistributionDatatableData) {
    var list []*multi_market_overview.MultiMarketSummaryPriceBandDistributionDataTable = (*data).Datatable
    // 分组
    var groups = make(map[string][]*multi_market_overview.MultiMarketSummaryPriceBandDistributionDataTable)
    for _, item := range list {
        groups[item.Dimention] = append(groups[item.Dimention], item)
    }
    // 组内排序
    for _, dataTables := range groups {
        // 从小到大排序(稳定排序)
        sort.SliceStable(dataTables, func(i, j int) bool {
            if GetPriceValue(dataTables[i].PriceBrand) < GetPriceValue(dataTables[j].PriceBrand) {
                return true
            }
            return false
        })
    }

    res := make([]*multi_market_overview.MultiMarketSummaryPriceBandDistributionDataTable, 0)
    for _, vlist := range groups {
        res = append(res, vlist...)
    }

    *data = &multi_market_overview.MultiMarketSummaryPriceBandDistributionDatatableData{
        Datatable: res,
    }
}

// GetPriceValue 价格带数据解析
func GetPriceValue(price string) int64 {
    priceRegexp := regexp.MustCompile(`^([0-9]+).*`)
    priceValues := priceRegexp.FindStringSubmatch(price)
    if priceValues == nil || len(priceValues) <= 1 {
        return 0
    }

    i, err := strconv.ParseInt(priceValues[1], 10, 64)
    if err != nil {
        return 0
    }
    return i
}

其中,排序的代码是 go sdk 提供的 go1.16.4/src/sort/slice.go :

// SliceStable sorts the slice x using the provided less
// function, keeping equal elements in their original order.
// It panics if x is not a slice.
//
// The less function must satisfy the same requirements as
// the Interface type's Less method.
func SliceStable(x interface{}, less func(i, j int) bool) {
    rv := reflectValueOf(x)
    swap := reflectSwapper(x)
    stable_func(lessSwap{less, swap}, rv.Len())
}



// Auto-generated variant of sort.go:stable
func stable_func(data lessSwap, n int) {
    blockSize := 20
    a, b := 0, blockSize
    for b <= n {
        insertionSort_func(data, a, b)
        a = b
        b += blockSize
    }
    insertionSort_func(data, a, n)
    for blockSize < n {
        a, b = 0, 2*blockSize
        for b <= n {
            symMerge_func(data, a, a+blockSize, b)
            a = b
            b += 2 * blockSize
        }
        if m := a + blockSize; m < n {
            symMerge_func(data, a, m, n)
        }
        blockSize *= 2
    }
}



package sort

// Auto-generated variant of sort.go:insertionSort
func insertionSort_func(data lessSwap, a, b int) {
    for i := a + 1; i < b; i++ {
        for j := i; j > a && data.Less(j, j-1); j-- {
            data.Swap(j, j-1)
        }
    }
}

猜你喜欢

转载自blog.csdn.net/universsky2015/article/details/125406363