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

В golang есть хороший способ получить кусочек ценностей с карты?

Если у меня есть отображение m, есть лучший способ получить срез значений v, тогда

package main
import (
  "fmt"
)

func main() {
    m := make(map[int]string)

    m[1] = "a"
    m[2] = "b"
    m[3] = "c"
    m[4] = "d"

    // Can this be done better?
    v := make([]string, len(m), len(m))
    idx := 0
    for  _, value := range m {
       v[idx] = value
       idx++
    }

    fmt.Println(v)
 }

Есть ли встроенная функция карты? Есть ли функция в пакете Go, или это лучший код для работы, если мне нужно?

4b9b3361

Ответ 1

К сожалению, нет. Нет встроенного способа сделать это.

Как побочная заметка, вы можете опустить аргумент емкости в своем создании среза:

v := make([]string, len(m))

Емкость подразумевается такой же, как длина здесь.

Ответ 2

В качестве дополнения к сообщению jimt:

Вы также можете использовать append, а не явно присваивать значения их индексам:

m := make(map[int]string)

m[1] = "a"
m[2] = "b"
m[3] = "c"
m[4] = "d"

v := make([]string, 0, len(m))

for  _, value := range m {
   v = append(v, value)
}

Обратите внимание, что длина равна нулю (пока нет элементов), но емкость (выделенное пространство) инициализируется количеством элементов m. Это делается так, чтобы append не требовалось выделять память каждый раз, когда заканчивается емкость среза v.

Вы также можете make срез без значения емкости и append выделить память для себя.

Ответ 3

Насколько мне известно, go не имеет способа для конкатенации строк/байтов в результирующую строку без создания как минимум/двух/копий.

В настоящее время вы должны вырастить байт [], поскольку все строковые значения const, THEN вы должны использовать встроенную строку, чтобы язык создавал "благословенный" строковый объект, который будет копировать буфер, поскольку что-то где-то могло имеют ссылку на адрес, поддерживающий байт [].

Если байт [] подходит, вы можете получить очень небольшое преимущество над функцией bytes.Join, сделав одно выделение и сделав копию, называет себя.

package main
import (
  "fmt"
)

func main() {
m := make(map[int]string)

m[1] = "a" ;    m[2] = "b" ;     m[3] = "c" ;    m[4] = "d"

ip := 0

/* If the elements of m are not all of fixed length you must use a method like this;
 * in that case also consider:
 * bytes.Join() and/or
 * strings.Join()
 * They are likely preferable for maintainability over small performance change.

for _, v := range m {
    ip += len(v)
}
*/

ip = len(m) * 1 // length of elements in m
r := make([]byte, ip, ip)
ip = 0
for  _, v := range m {
   ip += copy(r[ip:], v)
}

// r (return value) is currently a []byte, it mostly differs from 'string'
// in that it can be grown and has a different default fmt method.

fmt.Printf("%s\n", r)
}

Ответ 4

Вы можете использовать этот пакет maps:

go get https://github.com/drgrib/maps

Тогда все, что вам нужно позвонить, это

values := maps.GetValuesIntString(m)

Он безопасен для этой общей комбинации map. Вы можете generate другие безопасные для типов функции для любого другого типа map используя инструмент mapper в том же пакете.

Полное раскрытие: я создатель этого пакета. Я создал его, потому что я постоянно переписывал эти функции для map.