【JavaScript】Mapオブジェクト(値の更新)


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

Mapオブジェクトとは

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

今回のコード

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を作成(中身はまだ空)

const dict = new Map()

dictの値として配列sutandoTsukaiの各値(=各キャラの名前)、ダメージの初期値0をセット

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

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

  • 文字列.split(" ")により、スペースを区切り文字として文字列の配列に分割する
  • キャラの名前:target/ダメージ量:damageにそれぞれ格納
    (damageは計算するため数値として扱う=Number()を忘れずに)
for (let j = 0; j < fromKira.length ; j++) {
    const target = fromKira[j].split(" ")[0]
    const damage = Number(fromKira[j].split(" ")[1])

    if (//下記で説明
    }
}

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

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

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

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

③ Trueの場合:targetの値について、元の値+今回のdamageを足したものへ更新(set)
⇒ {Jyosuke=> 2}にdamage4をプラスして{Jyosuke=> 6}に変わる

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

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

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

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


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

(ただクレイジーダイヤモンドは本人(仗助くん)の傷は治せないんだ・・・なんて優しいかっこいい・・・。ロジックはちとややこしくなる!?w)

おまけ情報

配列に変換

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

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()


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

JavaScriptで連想配列を利用する際にObjectではなくMapを使うメリット

あとがき

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

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