it-swarm.com.de

Wie kann ich eine Golang-Karte in einer Anweisung erstellen?

Das ist mein Code:

var keys map[int]string
keys = make(map[int]string)

keys[1] = "aa"
keys[2] = "ab"
keys[3] = "ac"
keys[4] = "ba"
keys[5] = "bb"
keys[6] = "bc"
keys[7] = "ca"
keys[8] = "cb"
keys[9] = "cc"

Kann ich dasselbe in einer Anweisung und/oder in einer Zeile tun?

8
sensorario

Ja, Sie können eine Map mit einer einzelnen Anweisung erstellen (in der Spezifikation als composite literal bezeichnet): 

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

Wenn Sie sich innerhalb einer Funktion befinden, können Sie eine short Variablendeklaration verwenden:

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

Wenn sich zwischen den Schlüsseln und Werten Logik befindet, können Sie die Map auch mit einer Schleife initialisieren. "Setzen" Sie die Logik in den Schleifenkörper. Dies kann erheblich kürzer sein als die Verwendung eines zusammengesetzten Literal Aufzählens aller Schlüsselwertpaare, insbesondere wenn die Anzahl der Schlüsselwertpaare groß ist.

Ihr Beispiel kann damit umgesetzt 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)

Ausgabe (probiere 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 (mit einer anderen Logikimplementierung):

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)

Die Ausgabe ist "gleich". Versuchen Sie diese Variante auf dem Go Playground .

Und noch mehr Lösungen, jetzt nur den Loop-Body (Playground-Links: noch eine # 1 , noch eine # 2 ):

// 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 verwendet möglicherweise 2 Schleifen (eingebettet), die den Wert generieren, 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 dem Go Playground .

Wenn die Anzahl der Werte nicht groß ist, kann ein anderer praktikabler Ansatz darin bestehen, alle Elemente in einem string-Wert aufzulisten und Subslicing zu verwenden (was effizient ist, da keine neuen Backing-Arrays erstellt werden.

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)

Ausgabe (versuchen Sie dies auf dem Go Playground ):

map[9:cc 1:aa 2:ab 5:bb 8:cb 3:ac 4:ba 6:bc 7:ca]

Beachten Sie außerdem, dass, wenn der Schlüssel vom Typ int ist und der Schlüsselsatz (mehr oder weniger) zusammenhängend ist, es häufig effizienter ist (in Bezug auf Speicher und Leistung), stattdessen ein Slice zu 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)

Ausgabe (probiere 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 m3 sehen können, können Sie optionale Indizes im zusammengesetzten Literal verwenden, um den Index des folgenden Werts anzugeben. Mehr dazu hier: Keyed Items in der Golang Array-Initialisierung

7
icza

Mein bevorzugter Ansatz ist ein zusammengesetztes Literal in einer kurzen Variablendeklaration. In einigen Fällen kann eine Funktion dazu beitragen, das Durcheinander 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)
}

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

1
Peter Gloor