Перебирая все ключи карты

317

Есть ли способ получить список всех ключей на карте языка Go? Количество элементов определяется как len(), но если у меня есть карта вроде:

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

Как мне перебрать все ключи?

Мартин Редмонд
источник

Ответы:

547

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

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

или

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

В спецификации языка Go для forоператоров указано, что первое значение является ключом, вторая переменная является значением, но не обязательно должна присутствовать.

Джонатан Фейнберг
источник
22
Как возможное замечание, обратите внимание, что порядок итерации не определен. groups.google.com/d/msg/golang-nuts/YfDxpkI34hY/4pktJI2ytusJ
mna
23
Sudhir: спецификация языка golang явно определяет карты как имеющие неопределенный порядок ключей. Кроме того, начиная с Go 1, порядок ключей преднамеренно рандомизирован между прогонами, чтобы предотвратить зависимость от любого предполагаемого порядка.
Марк Ренуф
6
Обратите внимание, что это не изменяемая итерация, то есть удаление ключа потребует перезапуска итерации.
Рик Смит
Также для небольших наборов данных порядок отображения может быть предсказуемым.
Woot
14

Вот несколько простых способов получить sliceключи-карты.

// 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
источник
Возможно ли для Keysфункции взять карту с ключами любого типа, а не только со строками?
Роберт Т. МакГиббон
func Keys(m map[interface{}]interface{}) (keys []interface{}), @ RobertT.McGibbon вам нужно изменить функцию «прототип»
a8m
1
@ArielM. Это будет работать только для точного типа map[interface{}]interface{}. Go не поддерживает генерики. Вы не можете создать функцию с mapпараметром, который принимает карты с различными типами ключей.
icza
10

Есть ли способ получить список всех ключей на карте языка Go?

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

как мне перебрать все ключи?

Используйте принятый ответ:

for k, _ := range m { ... }
Шридхар
источник
1
Я думаю, что вы имели в виду for _, k := range v.MapKeys(), так как в вашем примере kбудет int индекс среза ключей
Брайан Лейшман