猿问

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

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


func SortedMapKeys(m map[string]string) (keyList []string) {

    for key := range m {

        keyList = append(keyList, key)

    }

    sort.Strings(keyList)

    return

}

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


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


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


慕森王
浏览 164回答 2
2回答

素胚勾勒不出你

由于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}对于中间解决方案,由于您可能只关心几种类型的组合,您可以使用类型开关来提取键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}

湖上湖

这是我的 0.02 美元。由于密钥提取逻辑不太可能改变,并且您希望将所有内容都放在一个地方,您可以创建变体并从中选择非零映射:type MapVariant struct {    Bool   map[string]bool    String map[string]string}func SortedMapKeys(variant MapVariant) (keyList []string) {    if variant.String != nil {        for k := range variant.String {            keyList = append(keyList, k)        }        goto SORT    }    if variant.Bool != nil {        for k := range variant.Bool {            keyList = append(keyList, k)        }        goto SORT    }SORT:    sort.Strings(keyList)    return}当然,您可以通过添加更多条件来避免 goto 语句,但我个人认为它更清晰。然后你可以使用如下函数:SortedMapKeys(MapVariant{    Bool: map[string]bool{"a": true, "b": false}})SortedMapKeys(MapVariant{    String: map[string]string{"c": "v1", "b": "v2"}})
随时随地看视频慕课网APP

相关分类

Go
我要回答