言語バージョン 1.15.3

公開日 November 9, 2020, GMT+9

更新日 January 12, 2021, GMT+9

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]

1次情報

Source file src/runtime/map.go

Go maps in action