【JavaScript】Mapオブジェクト（値の更新）

Mapオブジェクトを初めて使ってみたので、備忘録として簡単に残します。

## Mapオブジェクトとは

ES2015(ES6)から導入された、キーと値の組み合わせを保持することができるオブジェクト。

- 参考リンク<br>
[MDN - Map() コンストラクター](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map/Map)<br>
[Qiita - JavaScript　Mapオブジェクト](https://qiita.com/chihiro/items/9965cd7eca0380cf288c)

## 今回のコード

```JavaScript:KillerQueen.js

const sutandoTsukai = ["Jyosuke", "Okuyasu"]
const fromKira = ["Jyosuke 2", "Okuyasu 6", "Okuyasu 3", "Jyosuke 4"]
const dict = new Map()

for (let i = 0; i < sutandoTsukai.length; i++) {
    dict.set(sutandoTsukai[i], 0)
}

for (let j = 0; j < fromKira.length ; j++) {
    const target = fromKira[j].split(" ")[0]
    const damage = Number(fromKira[j].split(" ")[1])
    
    if (dict.get(target)) {
      dict.set(target, dict.get(target) + damage)
    } else {
      dict.set(target, damage)
    }
}

console.log(dict.get(sutandoTsukai[0]))
console.log(dict.get(sutandoTsukai[1]))
```

ジョジョみあふれるコードです。

これは吉良吉影 VS 東方仗助＆虹村億泰戦の際、四部ボス・吉良に受けたダメージについて
人ごと（スタンド使いごと）にデータを持たせて値を更新⇒最後に表示って流れですね。

配列`fromKira`の各値は"名前、ダメージ量"を表しています。

## 流れを簡単に説明

Mapオブジェクト`dict`を作成（中身はまだ空）

```JavaScript
const dict = new Map()
```

`dict`の値として配列`sutandoTsukai`の各値（＝各キャラの名前）、ダメージの初期値`0`をセット

```JavaScript
for (let i = 0; i < sutandoTsukai.length; i++) {
    dict.set(sutandoTsukai[i], 0)
}
```

配列`fromKira`について、まずはキャラの名前・ダメージ量を変数に振り分ける<br>

- 文字列.split(" ")により、スペースを区切り文字として文字列の配列に分割する
- キャラの名前：`target`／ダメージ量：`damage`にそれぞれ格納<br>
（damageは計算するため数値として扱う＝Number()を忘れずに）

```JavaScript
for (let j = 0; j < fromKira.length ; j++) {
    const target = fromKira[j].split(" ")[0]
    const damage = Number(fromKira[j].split(" ")[1])
    
    if (//下記で説明
    }
}
```

`fromKira`の各値を元に`dict`の値を更新
（吉良の攻撃ごとに、攻撃されたスタンド使いのダメージを増やすッ！）

```JavaScript
    if (dict.get(target)) {
      dict.set(target, dict.get(target) + damage)
    } else {
      dict.set(target, damage)
    }
```

① まず`dict`オブジェクト内の`target`の値を確認
　存在する場合はTrue、0の場合はFalse
⇒ 最初は`Jyosuke`も`Okuyasu`も初期値`0`なのでfalseになる

② Falseの場合：elseに入り`target`の値を今回の`damage`に更新（set）
⇒ {`Jyosuke`=> `0`}だったのが{`Jyosuke`=> `2`}に変わる

③ Trueの場合：`target`の値について、元の値＋今回の`damage`を足したものへ更新（set）
⇒ {`Jyosuke`=> `2`}に`damage`の`4`をプラスして{`Jyosuke`=> `6`}に変わる

※ dict.set内のdict.get（target）にて、元の値を取得（get）しています。

```JavaScript
console.log(dict.get(sutandoTsukai[0]))
console.log(dict.get(sutandoTsukai[1]))
```

あとは、各スタンド使いごとの更新後のダメージ値を表示するだけ。

どうでしょう
なんとなくイメージできたのでは？:blush:

---

将来的にはこのコードの中に、「クレイジーダイヤモンドが億泰の傷を治す」アクションとか入れたいッスね。
スタンド使いを増やして遊んでみてもいいかも。（康一くんとか、露伴先生とか）

（ただクレイジーダイヤモンドは本人（仗助くん）の傷は治せないんだ・・・なんて優しいかっこいい・・・。ロジックはちとややこしくなる！？ｗ）


## おまけ情報

### 配列に変換
Mapオブジェクトを配列に変換したい場合は、Array.fromで簡単にできるようです。
sortしたい時とかよさそう。

```JavaScript
const arr = Array.from(dict)
console.log(arr)
// [[Jyosuke, 6], [Okuyasu, 9]]
```

### forEach()を使う時
Mapオブジェクトに対してforEachで繰り返し処理を行う時、
引数の順は（key, value）ではなく（value, key）とするようです。
（完全にkey,valueの順だと思っててつまづいた・・・）

その他色々やり方があるみたいなので、詳しくは下記を。

[MDN - Map.prototype.forEach()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach)

---

※ ちなみに、Mapオブジェクトはそれ自体がイテレータなので
　for of 構文でループさせることができるようです。

[JavaScriptで連想配列を利用する際にObjectではなくMapを使うメリット](https://genzouw.com/entry/2019/07/04/120033/1648/#toc_id_10)

## あとがき
mapオブジェクト、グレートですよこいつはァ！
ジョジョ四部の仗助くん＆億泰コンビが好きすぎてつい書いてしまいました。

ネタが全く分からなかった人はジョジョ四部原作、もしくはアニメをお勧めいたします。
今回も読んでいただき、ありがとうございましたァン！:laughing: