dongshan4316 2019-05-29 10:36
浏览 97
已采纳

根据另一个切片中元素的顺序对切片进行排序

I am attempting to order a slice based on the order of the elements within another slice. My sort function works when I only have one of each type within my slice I want to order however when I start adding more elements the ordering breaks.

I have created an example within the Golang playground.

https://play.golang.org/p/e9sHIeV2qSf

I want to order my Variant slice by the Code field and have it the same as order as the codes appear in the Language struct.

Below is the sort function I am using:

sort.Slice(variants, func(i, j int) bool {
    for k, language := range languages {
        if language.Code == variants[i].Code {
            return i >= k
        }
    }

    return false
})

The current order it's returning is:

Sorted slice: [{Code:en-GB} {Code:en-US} {Code:en-GB} {Code:es-ES} {Code:en-GB} {Code:en-GB} {Code:en-GB} {Code:en-GB} {Code:es-ES}]

When the order within my Language struct is:

"en-GB", "en-US", "fr-FR", "es-ES"

  • 写回答

1条回答 默认 最新

  • dongtou2016 2019-05-29 10:44
    关注

    I think to do this, you need to build a ranking of your languages:

    var langMap map[string]int
    for i, lang := range languages {
        langMap[lang.Code] = i
    }
    

    With this, it becomes trivial to just look up the ranking of each item in variants, and return the appropriate value:

    sort.Slice(variants, func(i, j int) bool {
        iRank, jRank := langMap[variants[i].Code], langMap[variants[j].Code]
        return iRank < jRank
    })
    

    If there's a chance you may have inputs that are not in the pre-sorted list, you can sort them last:

    sort.Slice(variants, func(i, j int) bool {
        iRank, iExists := langMap[variants[i].Code]
        jRank, jExists := langMap[variants[j].Code]
        switch (
        case iExists && jExists:
            // Both exist in the pre-ordered list, so sort by rank
            return iRank < jRank
        case !iExists && !jExists:
            // Neither exists in the pre-ordered list, sort alphabetically
            return variants[i].Code < variants[j].Code
        case iExists:
            // Only i exists, so sort it before j
            return true
        default: // jExists
            // Only j exists, so sort it after i
            return false
        )
    
    })
    

    It is logically possible to do the same by looping through your reference list each time, as you're attempting, but it's much harder to reason about, and far less efficient.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 运筹学排序问题中的在线排序
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 lammps拉伸应力应变曲线分析
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题
  • ¥30 python代码,帮调试,帮帮忙吧