map(マップ)
このページでは豊富な例を用いてGolangのmapの取り扱い方を学ぶことができます。
mapはGolangの型の1つです。
他のプログラミング言語における連想配列に似た型であり、キー・バリュー形式で値を保持します。
array(配列)
や
slice(スライス)
ではインデックス番号が0から自動で振られているのに対し、
mapではインデックスのように指定するキーの型と値を自分で決めてバリューと紐付けることが可能です。
TL;DR
初期化
var mapper1 map[string]string
fmt.Println(mapper1)
==> map[]
fmt.Println(mapper1 == nil)
==> true
mapper2 := map[string]string{}
fmt.Println(mapper2)
==> map[]
fmt.Println(mapper2 == nil)
==> false
mapper3 := map[string]string{"name": "James", "age": "18"}
fmt.Println(mapper3)
==> map[age:18 name:James]
mapper4 := make(map[string]int, 0)
fmt.Println(mapper4)
==> map[]
fmt.Println(mapper4 == nil)
==> false
type Person struct {
ID int
Name string
}
mapper5 := map[int]Person{1: {ID: 111, Name: "Anny"}, 2: {ID: 16, Name: "Huey"}}
fmt.Println(mapper5)
==> map[1:{111 Anny} 2:{16 Huey}]
mapper6 := map[int]map[string]int{1: {"height": 150}, 2: {"width": 200}}
fmt.Println(mapper6)
==> map[1:map[height:150] 2:map[width:200]]
要素数
var mapper1 map[int]int
fmt.Println(len(mapper1))
==> 0
mapper2 := make(map[string]int, 50)
fmt.Println(len(mapper2))
==> 0
mapper3 := map[int]string{1: "Apple", 2: "Banana", 50: "Kiwi"}
fmt.Println(len(mapper3))
==> 3
type Student struct {
ID int
Name string
}
mapper4 := map[string][]Student{
"Math": {{1, "Jenny"}, {2, "Liam"}, {3, "Olivia"}, {4, "Sophia"}},
"Science": {{100, "Isabella"}, {19, "Lucas"}, {3, "Olivia"}},
}
// mapの要素数
fmt.Println(len(mapper4))
==> 2
// mapper4に格納されているslice([]Student)の長さ
fmt.Println(len(mapper4["Math"]))
==> 4
操作:取得
mapper1 := map[string]int{"math score": 100, "science score": 86}
fmt.Println(mapper1["math score"])
==> 100
mapper2 := map[string]map[string]map[int]string{
"Programming": {
"Languages": {1: "Golang", 2: "Python", 3: "Kotlin", 4: "JavaScript"},
},
}
fmt.Println(mapper2["Programming"]["Languages"][1])
==> Golang
type Language struct {
ID int
Name string
}
// キーにstring、バリューに「Languageの要素を持つslice」を持ったmap
mapper3 := map[string][]Language{
"myFavoriteLanguages": {{1, "Smalltalk"}, {2, "Delphi"}, {3, "Pascal"}, {4, "Lisp"}},
"myUnfavoredLanguages": {{0, "NaturalLanguage"}},
}
fmt.Println(mapper3["myFavoriteLanguages"])
==> [{1 Smalltalk} {2 Delphi} {3 Pascal} {4 Lisp}]
mapper4 := map[string]int{"first": 1, "second": 2, "third": 3}
// int型の初期値である0が返り値となる
fmt.Println(mapper4["fourth"])
==> 0
// for文を使用した取得例
mapper5 := map[string]string{"id": "X-123", "name": "Haruki"}
for key, value := range mapper5 {
fmt.Printf("key=%v value=%v\n", key, value)
}
==> key=id value=X-123
==> key=name value=Haruki
// 2つ目の返り値の使用
value1, ok1 := mapper5["id"]
value2, ok2 := mapper5["address"]
fmt.Printf("value1=%v ok1=%v\n", value1, ok1)
==> value1=X-123 ok1=true
fmt.Printf("value2=%v ok2=%v\n", value2, ok2)
==> value2= ok2=false
関連情報:forの使用方法
操作:追加
mapper1 := make(map[int]string)
mapper1[1] = "Golang"
mapper1[2] = "Python"
mapper1[100] = "Smalltalk"
fmt.Println(mapper1)
==> map[1:Golang 2:Python 100:Smalltalk]
type Fruit struct {
Name string
Calories int
}
var mapper2 map[int]Fruit
fmt.Println(mapper2 == nil)
// nilに要素の追加はできないので空の値を代入する
mapper2 = map[int]Fruit{}
mapper2[1] = Fruit{"Kiwi", 100}
mapper2[2] = Fruit{"Banana", 200}
fmt.Println(mapper2)
==> map[1:{Kiwi 100} 2:{Banana 200}]
操作:削除
mapper1 := map[int]string{1: "Golang", 2: "Kotlin"}
delete(mapper1, 2)
fmt.Println(mapper1)
==> map[1:Golang]
type Language struct {
ID int
Name string
}
mapper2 := map[string]Language{"go": {1, "Golang"}, "python": {2, "Python"}}
fmt.Println(mapper2)
==> map[go:{1 Golang} python:{2 Python}]
for key, _ := range mapper2 {
// キーがgoのものを削除
if key == "go" {
delete(mapper2, key)
}
}
fmt.Println(mapper2)
==> map[python:{2 Python}]
type Person struct {
Name string
FavoriteFruit map[int]string
}
mapper3 := map[int]Person{
1: {"Tadao", map[int]string{1: "Peach", 2: "Banana"}},
2: {"Kengo", map[int]string{1: "Graph"}},
}
fmt.Println(mapper3)
==> map[1:{Tadao map[1:Peach 2:Banana]} 2:{Kengo map[1:Graph]}]
delete(mapper3[1].FavoriteFruit, 2)
fmt.Println(mapper3)
==> map[1:{Tadao map[1:Peach]} 2:{Kengo map[1:Graph]}]
// 指定されたキーがない場合は何もしません
mapper4 := map[string]string{"key": "value"}
fmt.Println(mapper4)
==> map[key:value]
delete(mapper4, "value")
fmt.Println(mapper4)
==> map[key:value]
解説
初期化
mapはmap[キーの型]バリューの型
という形式で初期化できます。
波括弧{}
を使用することで初期値を設定することも可能です。
また、組み込み関数のmake
を使用して初期化することもできます。
make
を使用する場合、第1引数に型、第2引数に初期化時に確保したい要素数のスペースを指定します。
変数に初期値を明示的に指定しない場合、その変数にはnil
が初期値として設定されます。
var mapper1 map[int]int
fmt.Println(mapper1)
==> map[]
fmt.Println(mapper1 == nil)
==> true
mapper2 := map[int]int{}
fmt.Println(mapper2)
==> map[]
fmt.Println(mapper2 == nil)
==> false
mapper3 := map[string]int{"id": 10, "score": 95}
fmt.Println(mapper3)
==> map[id:10 score:95]
mapper4 := make(map[string]map[string]map[string]map[string]string, 50)
fmt.Println(mapper4)
==> map[]
fmt.Println(mapper4 == nil)
==> false
要素数
mapは組み込み関数のlen
を使用することで要素数を取得することができます。
組み込み関数のmake
の第2引数で指定した値は要素数のスペースであり、要素数自体ではないので注意してください。
mapper1 := map[int]int{1: 100}
fmt.Println(len(mapper1))
==> 1
// 第2引数はあくまで要素数のスペース(メモリ上の領域)
mapper2 := make(map[string]string, 1000)
fmt.Println(len(mapper2))
==> 0
// 要素を追加して初めて要素数が増える
mapper2["languageName"] = "Golang"
fmt.Println(len(mapper2))
==> 1
操作:取得
取得したい要素が入っているmapの後ろに角括弧([]
)を記述し、その中に取得したい要素のキーを同一の型で指定します。
複数の階層を持つmapの場合は、更に後ろに角括弧を続けてキーを指定します。
mapで値を取得する際、2つ目の返り値には指定したキーが存在しているかどうかがbool型で返ってきます。
なお、存在しないキーを指定した場合は指定したバリューのデフォルトの初期値が返却されます。
mapper1 := map[int]string{1: "first", 2: "second"}
fmt.Println(mapper1[1])
==> first
value1, ok1 := mapper1[1]
value2, ok2 := mapper1[100]
fmt.Printf("value1=%v ok1=%v\n", value1, ok1)
==> value1=first ok1=true
fmt.Printf("value2=%v ok2=%v\n", value2, ok2)
==> value2= ok2=false
mapper2 := map[string]map[string]string{"yesterday": {"breakfast": "cereal", "lunch": "sandwich", "dinner": "pizza"}}
fmt.Println(mapper2["yesterday"]["dinner"])
==> pizza
操作:追加
要素を追加したいmapの後ろに角括弧([]
)でキーを指定し、代入したい値を=
で指定することで要素を追加することができます。
初期化の仕方によってはnil
で初期化されている場合があります。その場合は空のmapを代入し、その後に要素を追加する処理を記述してください。
var mapper1 map[int]string
// nilで初期化されている
fmt.Println(mapper1 == nil)
==> true
// 空の値を代入して要素を追加できるようにする
mapper1 = map[int]string{}
fmt.Println(mapper1 == nil)
==> false
mapper1[10] = "ten"
fmt.Println(mapper1)
==> map[10:ten]
mapper2 := make(map[int]string)
// nilで初期化されていない
fmt.Println(mapper2 == nil)
==> false
mapper2[0] = "zero"
fmt.Println(mapper2)
==> map[0:zero]
mapper3 := map[string]int{"Math": 80, "Physics": 90, "History": 10}
// nilで初期化されていない
fmt.Println(mapper3 == nil)
==> false
mapper3["PE"] = 100
fmt.Println(mapper3)
==> map[History:10 Math:80 PE:100 Physics:90]
操作:削除
組み込み関数のdelete
を使用することで特定の要素を削除することができます。
deleteには第1引数に対象のmap、第2引数に削除したい要素のキーを指定します。
なお、deleteの第2引数に指定したキーが存在しない場合、deleteは対象のmapに対して何もしません。
mapper1 := map[float64]int{3.14: 3, 1.4142: 1}
fmt.Println(mapper1)
==> map[1.4142:1 3.14:3]
delete(mapper1, 1.4142)
fmt.Println(mapper1)
==> map[3.14:3]
// 指定されたキーがない場合
mapper2 := map[string]int{"first": 1}
fmt.Println(mapper2)
==> map[first:1]
delete(mapper2, "second")
fmt.Println(mapper2)
==> map[first:1]