Подтвердить что ты не робот

Получение части ключей с карты

Есть ли более простой/лучший способ получить кусочек ключей с карты в Go?

В настоящее время я повторяю карту и копирую ключи в срез:

i := 0
keys := make([]int, len(mymap))
for k := range mymap {
    keys[i] = k
    i++
}
4b9b3361

Ответ 1

Например,

package main

func main() {
    mymap := make(map[int]string)
    keys := make([]int, 0, len(mymap))
    for k := range mymap {
        keys = append(keys, k)
    }
}

Чтобы эффективно работать в Go, важно минимизировать выделение памяти.

Ответ 2

Это старый вопрос, но здесь мои два цента. Ответ PeterSO немного более краткий, но немного менее эффективный. Вы уже знаете, как сильно это будет, поэтому вам даже не нужно использовать append:

keys := make([]int, len(mymap))

i := 0
for k := range mymap {
    keys[i] = k
    i++
}

В большинстве ситуаций это, вероятно, не будет иметь большого значения, но это не намного больше работает, и в моих тестах (используя карту с 1 000 000 случайных клавиш int64, а затем генерируя массив ключей десять раз с каждым метод), было примерно на 20% быстрее назначать элементы массива напрямую, чем использовать append.

Несмотря на то, что установка емкости устраняет перераспределение, добавьте еще одну дополнительную работу, чтобы проверить, достигли ли вы емкости на каждом добавлении.

Ответ 3

Вы также можете взять массив ключей с типом []Value методом MapKeys структуры Value из пакета "отразить":

package main

import (
    "fmt"
    "reflect"
)

func main() {
    abc := map[string]int{
        "a": 1,
        "b": 2,
        "c": 3,
    }

    keys := reflect.ValueOf(abc).MapKeys()

    fmt.Println(keys) // [a b c]
}

Ответ 4

Лучшим способом сделать это будет использование append:

keys = []int{}
for k := range mymap {
    keys = append(keys, k)
}

Кроме того, вы не повезло - Go не очень выразительный язык.

Ответ 5

Я сделал схематичный тест по трем методам, описанным в других ответах.

Очевидно, что предварительное выделение фрагмента перед нажатием клавиш происходит быстрее, чем append, но, что удивительно, метод reflect.ValueOf(m).MapKeys() значительно медленнее, чем последний:

❯ go run scratch.go
populating
filling 100000000 slots
done in 56.630774791s
running prealloc
took: 9.989049786s
running append
took: 18.948676741s
running reflect
took: 25.50070649s

Вот код: https://play.golang.org/p/Z8O6a2jyfTH (запуск его на детской площадке прерывается, утверждая, что это занимает слишком много времени, поэтому, хорошо, запустите его локально.)

Ответ 6

Посетите https://play.golang.org/p/dx6PTtuBXQW.

package main

import (
    "fmt"
    "sort"
)

func main() {
    mapEg := map[string]string{"c":"a","a":"c","b":"b"}
    keys := make([]string, 0, len(mapEg))
    for k := range mapEg {
        keys = append(keys, k)
    }
    sort.Strings(keys)
    fmt.Println(keys)
}