【Go】基本文法メモ⑤(連想配列・ Range)

# 概要
[A Tour of Go](https://tour.golang.org/)の順番に沿ってGoの基本で個人的に学習したことをまとめています。


| No | 記事 |
|------|---------|
|    1  |   [【Go】基本文法①(基礎)](https://qiita.com/k-penguin-sato/items/1d0e1c6b4bf937996cd3)|
|    2  |   [【Go】基本文法②(フロー制御文)](https://qiita.com/k-penguin-sato/items/31b45fd3914797b654f0)|
|    3  |  [【Go】基本文法③(ポインタ・構造体)](https://qiita.com/k-penguin-sato/items/62dfe0f93f56e4bf9157)|
|    4  |  [【Go】基本文法④(配列・スライス)](https://qiita.com/k-penguin-sato/items/daad9986d6c42bdcde90)|
|    5  |   __〜〜【Go】基本文法⑤(Maps・ Range)「今ココ」〜〜__|
|    6  |    [【Go】基本文法⑥(インターフェース)](https://qiita.com/k-penguin-sato/items/885a61d819cc431304f5)     |
|    7  |     [【Go】基本文法⑦(並行処理)](https://qiita.com/k-penguin-sato/items/5b09fa89d8d231bcdac8)    |
|    8  |    [【Go】基本文法総まとめ](https://qiita.com/k-penguin-sato/items/deaeab18aa416496e273)     |



今回は `Maps(連想配列)` と `Range` に焦点を当てて学習しました。

# Maps(連想配列)
配列が整数値を使って要素を指定するのに対し、`Maps連想配列` は `キー (key)` というデータを使って要素を指定するデータ構造です。
`Ruby` で言う `Hash` 、 `Python` で言う `dictionary` にあたります。

### Maps(連想配列)の宣言方法
Maps(連想配列) は主に以下のように宣言します。

```
①組み込み関数make()を利用して宣言
②初期値を指定して宣言
```
### ①組み込み関数make()を利用して宣言

組み込み関数 `make()` 関数は指定された型の、初期化され使用できるようにしたマップを返します。
`make()` を利用する際には以下の様にマップの初期化を行います。

```Golang
make(map[キーの型]値の型, キャパシティの初期値)
make(map[キーの型]値の型)// キャパシティの初期値は、省略も可能
```
組み込み関数の`make()` によって作成された `Maps(連想配列)` に以下の様に `key` と `value` を入れる事ができます。

```Golang
map[keyの値] = valueの値
```

実際に以下の様に `Maps(連想配列)` を作成する事ができます。

```Golang
func main() {
    mapEx := make(map[string]string, 2) //マップの宣言
	fmt.Println(mapEx) //=> map[] //宣言された空のマップ
	
	mapEx["firstName"] = "Mike" //マップにkeyとvalueを挿入する。
	mapEx["lastName"] = "Smith"
   
    fmt.Println(mapEx) //=> map[lastName:Smith firstName:Mike]
}
```

### ②初期値を指定して宣言
組み込み関数 `make()` を使用せずとも、以下の様に初期値を指定して宣言する事で、`Maps(連想配列)` を作成する事ができます。

```Golang
var 変数名 map[key]value = map[key]value{key1: value1, key2: value2, ..., keyN: valueN}
```

実際に以下の様に `Maps(連想配列)` を作成する事ができます。

```Golang
var mapEx = map[string]string{"firstName":"John", "lastName": "Smith"}

func main() {
    fmt.Println(mapEx) //=> map[lastName:Smith firstName:Mike]
}
```

### Maps(連想配列)のゼロ値

Maps(連想配列)の初期値を指定しない場合、変数は `nil (nil マップ)` に初期化されます。
`nil マップ` は要素を格納することができず、要素を格納する場合はマップの初期化を行う必要があります。

```Golang
map [キーの型] 値の型
// map の後ろの [ ] にキーの型を、その後ろに値の型を指定します。
```

```Golang 
var map1 map[string]int

func main() {
	fmt.Println(map1) //=> map[] //nilマップ
}
```

### Maps(連想配列)への要素の挿入や更新

以下の様にMaps(連想配列)への要素の挿入や更新を行う事ができます。

```Golang
map[key] = elem
```

実際に上記の方法で挿入や更新ができる事を確認します。

```Golang
func main() {
   mapEx := make(map[string]int)
   mapEx["ele1"] = 1 //要素の挿入
   fmt.Println(mapEx)
   
   mapEx["newEle"] = 2 //要素の更新
   fmt.Println(mapEx) 
}

```

### Maps(連想配列)からの要素の取得

以下の様にMaps(連想配列)からの要素の取得を行う事ができます。

```Golang
map[key]
```

実際に上記の方法で要素の取得ができる事を確認します。

```Golang
func main() {
   mapEx := map[string]string{"firstName":"John", "lastName": "Smith"}
   
   fmt.Println(mapEx["firstName"]) //=> John
   fmt.Println(mapEx["lastName"]) //=> Smith
}
```

### Maps(連想配列)の要素の削除

以下の様にMaps(連想配列)の要素の削除を行う事ができます。

```Golang
delete(mapEx, key)
```
実際に上記の方法で要素の削除ができる事を確認します。

```Golang
func main() {
   mapEx := map[string]string{"firstName":"John", "lastName": "Smith"}
   delete(mapEx, "firstName") //mapExの"firstName"を削除

   fmt.Println(mapEx["firstName"]) //=>
   fmt.Println(mapEx["lastName"]) //=> Smith
}
```

# Range( `for` の `range`節)

`range` は、`Slices(スライス)` や、`Maps(マップ)` をひとつずつ反復処理するために使います。

### Sliceの場合の`range`
スライスを `range` で繰り返す場合、`range` は反復毎に2つの変数を返します。 
1つ目の変数は `インデックス(index)` で、2つ目は `インデックスの場所の要素(value)` です。

```Golang
var slice = []string{"Golang", "Ruby", "Javascript", "Python"}

func main() {
	for index, value := range slice {
	    fmt.Println(index, value)
		//=> 0 Golang
		//=> 1 Ruby
		//=> 2 Javascript
		//=> 3 Python
	}
}
```

### Mapの場合の`range`
マップを `range` で繰り返す場合、**反復される順番がランダムになります**が、それ以外はスライスと同じです。反復毎に2つの変数を返し、1つ目の変数は `キー(key)` で、2つ目は `キーの場所の要素(value)` です。

```Golang
var mapping = map[string]int{
	"one":   1,
	"two":   2,
	"three": 3,
	"four":  4,
	"five":  5,
}

func main() {
	for key, value := range mapping {
		fmt.Println(key, value)
		//=> four 4
		//=> five 5
		//=> one 1
		//=> two 2
		//=> three 3
	}
}
```
- [オンラインで動作をみる](https://go.dev/play/p/VAYqNVY9w1F) @ Go Playground


### `index` や `value` の省略
インデックスや値は、 ` _ ` へ代入することで省略することができます。
__インデックスのみが必要な場合は以下の様になります。__

```Golang
var slice = []string{"Golang", "Ruby", "Javascript", "Python"}

func main() {
	for index, _ := range slice {
	    fmt.Println(index)
		//=> 0 
		//=> 1 
		//=> 2 
		//=> 3 
	}
}
```
__バリューのみが必要な場合は以下の様になります。__

```Golang
var slice = []string{"Golang", "Ruby", "Javascript", "Python"}

func main() {
	for _, value := range slice {
	    fmt.Println(value)
		//=> Golang
		//=> Ruby
		//=> Javascript
		//=> Python
	}
}
```

### 反復処理を途中で止める、スキップする
`for` ループを途中で止める場合は `break`、それ以降の処理をスキップして次のループに進むには `continue` を使います。

```Golang
var slice = []string{"Golang", "Ruby", "Javascript", "Python"}

func main() {
	for _, value := range slice {
	    if "Golang" == value {
	        fmt.Println("Golang found")
	        continue // 次の処理にスキップ
	    }

	    if "Javascript" == value {
	        fmt.Println("Javascript found!")
	        break // ループから抜ける
	    }

        fmt.Println(value, "is not Golang")
	}
}

// Golang found
// Ruby is not Golang
// Javascript found!
// -->Python には辿り付かない
```

# 参考
[My journey of Go⑤](https://k-blog0130.herokuapp.com/posts/18)
[お気軽Goプログラミング（forのrange節）](http://www.geocities.jp/m_hiroi/golang/abcgo02.html)
[はじめてのGo言語](http://cuto.unirita.co.jp/gostudy/post/go_map/)