Li Jinyao
Li Jinyao

Reputation: 978

Write a function to get a slice of string keys from a map no matter what value type the map is

I want to write a function to get all keys from a map as a slice of string which key type is string and the value could be any other type.

Like this but can have any kind of map[string]... as input.

func mapLowCaseKeys(v map[string]string) []string {
    keys := make([]string, len(v))
    i := 0
    for key := range v {
        keys[i] = strings.ToLower(key)
        i++
    }
    return keys
}

Actually I want achive Object.keys() in Javascript.

I've tried use map[string]interface{} as the function's paramter type but it can't just pass any specific map to that function, is this possible in golang?

Upvotes: 0

Views: 812

Answers (1)

nightfury1204
nightfury1204

Reputation: 4654

You can make use MapKeys in reflect package to do that(ref: https://golang.org/pkg/reflect/#Value.MapKeys).

MapKeys returns a slice containing all the keys present in the map, in unspecified order. It panics if v's Kind is not Map. It returns an empty slice if v represents a nil map.

An example is given below (playground link: https://play.golang.org/p/xhDtmbGUyz0):

package main

import (
    "fmt"
    "reflect"
)

func main() {
    fmt.Println(mapLowCaseKeys(map[string]float64{
        "key1" : 1.2,
    }))

    fmt.Println(mapLowCaseKeys(map[string]interface{} {
        "key1" : 1.2,
        "key2" : map[string]string{"kk": "3"},
    }))

    fmt.Println(mapLowCaseKeys(map[int]float64{
         11 : 1.2,
    }))

    fmt.Println(mapLowCaseKeys(nil))
}

func mapLowCaseKeys(v interface{}) []string {
    keys := []string{}
    value := reflect.ValueOf(v)
    if value.Kind() == reflect.Map {
        for _, v := range value.MapKeys() {
            if v.Kind() == reflect.String {
                keys = append(keys, v.String())
            }
        }
        return keys
    } else {
        fmt.Println("it is not a map!!")
        return keys
    }
}

Upvotes: 1

Related Questions