Ответ 1
К сожалению, нет. Нет встроенного способа сделать это.
Как побочная заметка, вы можете опустить аргумент емкости в своем создании среза:
v := make([]string, len(m))
Емкость подразумевается такой же, как длина здесь.
Если у меня есть отображение 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, или это лучший код для работы, если мне нужно?
К сожалению, нет. Нет встроенного способа сделать это.
Как побочная заметка, вы можете опустить аргумент емкости в своем создании среза:
v := make([]string, len(m))
Емкость подразумевается такой же, как длина здесь.
В качестве дополнения к сообщению 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
выделить память для себя.
Насколько мне известно, 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)
}
Вы можете использовать этот пакет maps
:
go get https://github.com/drgrib/maps
Тогда все, что вам нужно позвонить, это
values := maps.GetValuesIntString(m)
Он безопасен для этой общей комбинации map
. Вы можете generate
другие безопасные для типов функции для любого другого типа map
используя инструмент mapper
в том же пакете.
Полное раскрытие: я создатель этого пакета. Я создал его, потому что я постоянно переписывал эти функции для map
.