これは私のコードです:
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"
1つのステートメントや1行で同じことを実行できますか?
はい、単一のステートメント(仕様では composite literal と呼ばれる)でマップを作成できます。
var keys = map[int]string{
1: "aa",
2: "ab",
3: "ac",
4: "ba",
5: "bb",
6: "bc",
7: "ca",
8: "cb",
9: "cc",
}
または、関数内にいる場合は、 短い変数宣言 を使用できます。
keys := map[int]string{
1: "aa",
2: "ab",
3: "ac",
4: "ba",
5: "bb",
6: "bc",
7: "ca",
8: "cb",
9: "cc",
}
キーと値の間にロジックがある場合、ループを使用してマップを初期化することもできます。ロジックをループ本体に「挿入」します。これは、特にキーと値のペアの数が多い場合に、すべてのキーと値のペアを列挙する composite literal を使用するよりも大幅に短くなる可能性があります。
あなたの例はこれで実装できます:
m := map[int]string{}
for i := 0; i < 9; i++ {
m[i+1] = string("abc"[i/3]) + string("abc"[i%3])
}
fmt.Println(m)
出力( Go Playground で試してください):
map[5:bb 8:cb 4:ba 2:ab 3:ac 6:bc 7:ca 9:cc 1:aa]
このソリューションのバリアント(異なるロジック実装を使用):
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)
出力は「同じ」です。 Go Playground でこのバリアントを試してください。
さらに、ループ本体のみを投稿するソリューション(プレイグラウンドリンク: another#1 、 another#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)
別のアプローチでは、値を生成し、値からキーを計算する2つのループ(埋め込み)を使用する場合があります。
for i := 'a'; i <= 'c'; i++ {
for j := 'a'; j <= 'c'; j++ {
m[int((i-'a')*3+j-'a'+1)] = string(i) + string(j)
}
}
Go Playground でこれを試してください。
値の数が多くない場合、別の実行可能なアプローチは、1つのstring
値内のすべての要素を列挙し、サブスライスを使用することです(新しいバッキング配列が作成されないため効率的です。文字列は共有されます):
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)
出力( Go Playground でこれを試してください):
map[9:cc 1:aa 2:ab 5:bb 8:cb 3:ac 4:ba 6:bc 7:ca]
また、キーがint
型で、キーのセットが(多かれ少なかれ)連続している場合、代わりにスライスを使用する方が効率的(メモリとパフォーマンスの両方)であることが多いことに注意してください。
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)
出力( 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"]
3番目の例でわかるようにm3
、複合リテラルでオプションのインデックスを使用して、後続の値のインデックスを指定できます。詳細はこちら: golang配列初期化のキー付きアイテム
私の好ましいアプローチは、短い変数宣言の複合リテラルです。場合によっては、関数が混乱を減らすのに役立つことがあります。
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)
}
https://play.golang.org/p/Rrb9ChBkXW で実際の動作をご覧ください