Iterando todas as teclas de um mapa

316

Existe uma maneira de obter uma lista de todas as chaves em um mapa de idiomas do Go? O número de elementos é dado por len(), mas se eu tiver um mapa como:

m := map[string]string{ "key1":"val1", "key2":"val2" };

Como iterar sobre todas as chaves?

Martin Redmond
fonte

Respostas:

546

https://play.golang.org/p/JGZ7mN0-U-

for k, v := range m { 
    fmt.Printf("key[%s] value[%s]\n", k, v)
}

ou

for k := range m {
    fmt.Printf("key[%s] value[%s]\n", k, m[k])
}

As especificações de idioma Go para forinstruções especificam que o primeiro valor é a chave, a segunda variável é o valor, mas não precisa estar presente.

Jonathan Feinberg
fonte
22
Como possível pegada, observe que a ordem da iteração é indefinida. groups.google.com/d/msg/golang-nuts/YfDxpkI34hY/4pktJI2ytusJ
mna
23
Sudhir: a especificação do idioma golang define explicitamente os mapas como tendo ordem indefinida de chaves. Além disso, desde o Go 1, a ordem das teclas é intencionalmente aleatória entre as execuções para evitar a dependência de qualquer ordem percebida.
21813 Mark Renouf
6
Observe que essa não é uma iteração mutável, ou seja, excluir uma chave exigirá que você reinicie a iteração.
21713 Rick
Também para conjuntos de dados pequenos, a ordem do mapa pode ser previsível.
Woot
14

Aqui está uma maneira fácil de obter sliceas chaves do mapa.

// Return keys of the given map
func Keys(m map[string]interface{}) (keys []string) {
    for k := range m {
        keys = append(keys, k)
    }
    return keys
}

// use `Keys` func
func main() {
    m := map[string]interface{}{
        "foo": 1,
        "bar": true,
        "baz": "baz",
    }
    fmt.Println(Keys(m)) // [foo bar baz]
}
a8m
fonte
É possível que a Keysfunção faça um mapa com chaves de qualquer tipo, não apenas cadeias de caracteres?
Robert T. McGibbon
func Keys(m map[interface{}]interface{}) (keys []interface{}), @ RobertT.McGibbon você precisa mudar a função de "protótipo"
a8m
1
@ArielM. Isso funcionaria apenas para o tipo exato map[interface{}]interface{}. O Go não suporta genéricos. Você não pode criar uma função com um mapparâmetro que aceite mapas com diferentes tipos de chave.
icza 17/06/2015
10

Existe uma maneira de obter uma lista de todas as chaves em um mapa de idiomas do Go?

ks := reflect.ValueOf(m).MapKeys()

como iterar sobre todas as chaves?

Use a resposta aceita:

for k, _ := range m { ... }
Sridhar
fonte
1
Eu acho que você quis dizer for _, k := range v.MapKeys(), já que no seu exemplo, kseria o índice int da fatia de chaves
Brian Leishman