2016-12-10 2 views

Antwort

21

Ja, können Sie eine Karte mit einer einzigen Anweisung erstellen (eine so genannte composite literal in der Spezifikation):

var keys = map[int]string{ 
    1: "aa", 
    2: "ab", 
    3: "ac", 
    4: "ba", 
    5: "bb", 
    6: "bc", 
    7: "ca", 
    8: "cb", 
    9: "cc", 
} 

Oder, wenn Sie innerhalb einer Funktion sind, können Sie eine short variable declaration verwenden:

keys := map[int]string{ 
    1: "aa", 
    2: "ab", 
    3: "ac", 
    4: "ba", 
    5: "bb", 
    6: "bc", 
    7: "ca", 
    8: "cb", 
    9: "cc", 
} 
6

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

1

Mein bevorzugter Ansatz ist ein zusammengesetztes Literal in einer kurzen Variablendeklaration. In einigen Fällen kann eine Funktion helfen, Unordnung zu reduzieren.

package main 

import (
    "fmt" 
) 

// initMap initializes a map with an integer key starting at 1 
func initMap(sa []string) map[int]string { 
    m := make(map[int]string, len(sa)) 
    for k, v := range sa { 
     m[k+1] = v // add 1 to k as it is starting at base 0 
    } 
    return m 
} 

// main is the entry point of any go application 
func main() { 
    // My preferred approach is a composite literal in a short variable declaration 
    keys := map[int]string{1: "aa", 2: "ab", 3: "ac", 4: "ba", 5: "bb", 6: "bc", 7: "ca", 8: "cb", 9: "cc"} 
    fmt.Println(keys) 

    // Using a function to initialize the map might help to avoid clutter 
    keys2 := initMap([]string{"aa", "ab", "ac", "ba", "bb", "bc", "ca", "cb", "cc"}) 
    fmt.Println(keys2) 
} 

es in Aktion bei https://play.golang.org/p/Rrb9ChBkXW

+0

Ihrer 'initMap' Funktion sollte eine Anfangskapazität für die Karte als zweites Argument an' make' liefern: 'len (sa)'. – seh

+1

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. –

+0

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

Verwandte Themen