Jeśli mam mapę m, czy jest lepszy sposób na uzyskanie wycinka wartości 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)
}
Czy istnieje wbudowana funkcja mapy? Czy w pakiecie Go jest funkcja, czy jest to najlepszy kod do zrobienia, jeśli muszę?
_
zeidx
i używaćidx-1
podczas przypisywania wartości plaster.Odpowiedzi:
Niestety nie. Nie ma na to wbudowanego sposobu.
Na marginesie, możesz pominąć argument pojemności podczas tworzenia wycinka:
v := make([]string, len(m))
Zakłada się, że pojemność jest taka sama jak długość tutaj.
źródło
Jako dodatek do posta jimta:
Możesz także użyć
append
zamiast jawnie przypisywać wartości do ich indeksów: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) }
Zauważ, że długość wynosi zero (brak jeszcze elementów), ale pojemność (przydzielone miejsce) jest inicjowana liczbą elementów
m
. Dzieje się tak, abyappend
nie trzeba było przydzielać pamięci za każdym razem, gdyv
skończy się pojemność wycinka .Możesz także
make
wycinek bez wartości pojemności i pozwolić naappend
alokację pamięci dla siebie.źródło
make([]appsv1.Deployment, len(d))
spowoduje dołączenie do kilku pustych elementów, które zostały utworzone podczas przydzielanialen(d)
pustych elementów.O ile obecnie wiem, go nie ma metody łączenia ciągów / bajtów w wynikowym ciągu bez tworzenia co najmniej / dwóch / kopii.
Obecnie musisz powiększyć bajt [], ponieważ wszystkie wartości łańcuchowe są stałymi, WTEDY musisz użyć wbudowanego ciągu znaków, aby język utworzył 'błogosławiony' obiekt łańcuchowy, do którego skopiuje bufor, ponieważ coś gdzieś może mieć odniesienie na adres z kopią bajtu [].
Jeśli bajt [] jest odpowiedni, możesz uzyskać niewielką przewagę nad bajtami. Dołącz do funkcji, dokonując jednej alokacji i wykonując kopiowanie wywołuje siebie.
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) }
źródło
Możesz użyć tego
maps
pakietu:go get https://github.com/drgrib/maps
Wtedy wszystko, co musisz zadzwonić, to
To jest bezpieczne dla tego typowego
map
połączenia. W tym samym pakiecie można korzystać zgenerate
innych funkcji bezpiecznych dla typów dla dowolnego innego typumap
użyciamapper
narzędzia.Pełne ujawnienie: jestem twórcą tego pakietu. Stworzyłem go, ponieważ wielokrotnie przepisałem te funkcje
map
.źródło
Niekoniecznie lepiej, ale sposób czystszy to zrobić poprzez określenie zarówno DŁUGOŚĆ plasterek i pojemność jak
txs := make([]Tx, 0, len(txMap))
// Defines the Slice capacity to match the Map elements count txs := make([]Tx, 0, len(txMap)) for _, tx := range txMap { txs = append(txs, tx) }
Pełny przykład:
package main import ( "github.com/davecgh/go-spew/spew" ) type Tx struct { from string to string value uint64 } func main() { // Extra touch pre-defining the Map length to avoid reallocation txMap := make(map[string]Tx, 3) txMap["tx1"] = Tx{"andrej", "babayaga", 10} txMap["tx2"] = Tx{"andrej", "babayaga", 20} txMap["tx3"] = Tx{"andrej", "babayaga", 30} txSlice := getTXsAsSlice(txMap) spew.Dump(txSlice) } func getTXsAsSlice(txMap map[string]Tx) []Tx { // Defines the Slice capacity to match the Map elements count txs := make([]Tx, 0, len(txMap)) for _, tx := range txMap { txs = append(txs, tx) } return txs }
Proste rozwiązanie, ale wiele problemów. Przeczytaj ten wpis na blogu, aby uzyskać więcej informacji: https://web3.coach/golang-how-to-convert-map-to-slice-three-gotchas
źródło