Wenn zwischen Schlüsseln und Werten eine Logik besteht, können Sie auch eine Schleife verwenden, um die Zuordnung zu initialisieren. "Setzen" Sie die Logik in den Schleifenkörper. Dies kann wesentlich kürzer sein als die Verwendung einer composite literal Enumeration aller Schlüssel/Wert-Paare, insbesondere wenn die Anzahl der Schlüssel/Wert-Paare groß ist.
Ihr Beispiel kann dies realisiert werden:
m := map[int]string{}
for i := 0; i < 9; i++ {
m[i+1] = string("abc"[i/3]) + string("abc"[i%3])
}
fmt.Println(m)
Output (versuchen Sie es auf dem Go Playground):
map[5:bb 8:cb 4:ba 2:ab 3:ac 6:bc 7:ca 9:cc 1:aa]
Eine Variante dieser Lösung (eine andere Logik Implementierung verwendet wird):
m := map[int]string{}
for i := 0; i < 9; i++ {
m[i+1] = "abc"[i/3:i/3+1] + "abc"[i%3:i%3+1]
}
fmt.Println(m)
Ausgang ist das "gleiche". Versuchen Sie diese Variante auf der Go Playground.
Und noch mehr Lösungen, jetzt nur noch die Schleifenkörper (Spielplatz Links: another #1, another #2): Entsendung
// Another #1:
m[i+1] = fmt.Sprintf("%c%c", "abc"[i/3], "abc"[i%3])
// Another #2:
m[i+1] = fmt.Sprintf("%c%c", 'a'+i/3, 'a'+i%3)
Ein anderer Ansatz 2 verwenden könnte Schleifen (eingebettet), die den Wert erzeugen und berechnet den Schlüssel aus dem Wert:
for i := 'a'; i <= 'c'; i++ {
for j := 'a'; j <= 'c'; j++ {
m[int((i-'a')*3+j-'a'+1)] = string(i) + string(j)
}
}
Versuchen Sie dies auf der Go Playground.Wenn die Anzahl der Werte nicht groß ist, kann ein anderer praktikabler Ansatz sein, alle Elemente in einem string
Wert aufzulisten und Subslicing zu verwenden (was effizient ist, da keine neuen Backing-Arrays erzeugt werden, das Backing Array der Strings) geteilt wird):
const s = "aaabacbabbbccacbcc"
m := map[int]string{}
for i := 0; i < 9; i++ {
m[i+1] = s[i*2 : i*2+2]
}
fmt.Println(m)
Output (versuchen Sie dies auf den Go Playground):
map[9:cc 1:aa 2:ab 5:bb 8:cb 3:ac 4:ba 6:bc 7:ca]
beachten Sie auch, dass, wenn die Schlüssel vom Typ int
und die Menge des Schlüssels ist (mehr oder weniger) angrenzt, O ften ist es effizienter, (beide Speicher und Performance-weise) stattdessen eine Scheibe verwenden:
m := make([]string, 10)
for i := 0; i < 9; i++ {
m[i+1] = fmt.Sprintf("%c%c", 'a'+i/3, 'a'+i%3)
}
fmt.Printf("%q\n", m)
m2 := []string{"", "aa", "ab", "ac", "ba", "bb", "bc", "ca", "cb", "cc"}
fmt.Printf("%q\n", m2)
m3 := []string{1: "aa", "ab", "ac", "ba", "bb", "bc", "ca", "cb", "cc"}
fmt.Printf("%q\n", m3)
Output (versuchen Sie es auf dem Go Playground):
["" "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc"]
["" "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc"]
["" "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc"]
Wie Sie im dritten Beispiel sehen können m3
können Sie optionale Indizes im zusammengesetzten Literal verwenden, um den Index des folgenden Wertes anzugeben. Mehr dazu hier: Keyed items in golang array initialization
Ihrer 'initMap' Funktion sollte eine Anfangskapazität für die Karte als zweites Argument an' make' liefern: 'len (sa)'. – seh
Die Kapazität ist wichtig für Slices, aber Karten funktionieren anders und haben keine Kapazität. Sie haben Recht, bei großen Karten können und sollten Sie einen optionalen Größenparameter in der make-Anweisung angeben. Im Fall von kleinen Karten, wie in diesem Beispiel, werden Sie wahrscheinlich keinen messbaren Leistungsgewinn erkennen. –
Gut, nennen Sie es "initial space", wie es die Spezifikation tut. Der Punkt ist, dass die Notwendigkeit einer nachfolgenden Zuordnung und Reorganisation der Karte vermieden wird. Es ist die "Fähigkeit, Tabellenwachstum zu vermeiden" angesichts seiner derzeitigen Zuteilung. – seh