如何在Go中获取地图键的排序列表?

Rhi*_*rva 3 sorting dictionary list go

让我们想象一下我有一张地图:map[string]string.我想获取此地图的排序键列表.所以我可以这样做:

func SortedMapKeys(m map[string]string) (keyList []string) {
    for key := range m {
        keyList = append(keyList, key)
    }
    sort.Strings(keyList)
    return
}
Run Code Online (Sandbox Code Playgroud)

然后我会有另一个类型的地图map[string]bool.我也想得到它的钥匙.但问题是函数SortedMapKeys接受一个map[string]string参数.所以我需要编写完全相同的函数,只有一个区别 - 它会接受一个map[string]bool.

出于显而易见的原因,它不是一种选择.如果有一天我想改变我获取和排序键的逻辑,我将需要跟踪和更新所有这些功能.此外,我将不得不为所有这些函数编写相同的单元测试,这些函数实际上做同样的事情,因为它们的主体是100%相等(代码重复).

有没有办法创建一个可以接受map[string] 任何东西的通用函数?

Jim*_*imB 5

由于map[string]bool与map[string]string和map[string]Whatever都是不同的类型,以创建单个函数来的所有可能的键进行排序的唯一方法map[string]*类型是通过反射.

func SortedMapKeys(m interface{}) (keyList []string) {
    keys := reflect.ValueOf(m).MapKeys()

    for _, key := range keys {
        keyList = append(keyList, key.Interface().(string))
    }
    sort.Strings(keyList)
    return
}
Run Code Online (Sandbox Code Playgroud)

对于中间解决方案,因为您可能只关注几种类型的组合,您可以使用类型开关来提取密钥

func SortedMapKeys(m interface{}) (keyList []string) {
    switch m := m.(type) {
    case map[string]string:
        for k := range m {
            keyList = append(keyList, k)
        }
    case map[string]bool:
        for k := range m {
            keyList = append(keyList, k)
        }
    default:
        panic("unknown map type")
    }

    sort.Strings(keyList)
    return
}
Run Code Online (Sandbox Code Playgroud)