7839

雑草魂エンジニアブログ

【JS】更新頻度が高いデータ構造に最適なMap オブジェクトを試した

最近、あるプロジェクトで初めて Map オブジェクトを使うことになり、これまで使ったことがなかったので調べてみました。備忘録として残しておく。

Map オブジェクトとは

developer.mozilla.org

Map オブジェクトとは、名前にもあるようにオブジェクトである。ES2015(ES6)から導入され、キーと値のペアを保持することができるオブジェクトである。

こう聞くと、Object と同じではないか?と思う。どちらも、キーと値のペアでデータを保持して、必要に応じてデータの出し入れが可能である。

違いとしては以下が挙げられる。

Map Object
キーの型 関数、オブジェクトなどの何でもいい String または Symbol のみ
キーの順序 挿入順 キーがStringの場合のみ、挿入順
素数 'size' プロパティで確認できる 素数を数える必要がある
反復処理 反復可能(iterable)プロトコルをもつ反復可能オブジェクト キーを指定して反復処理を行う必要がある

反復処理に関しては、下記の使い方で、反復処理が簡単に実装可能であることを確認してほしい。

iterable に関しても、詳細は公式を確認してほしい。 developer.mozilla.org

使い方

Mapの作成

const mapObj = new Map()
// 初期値を設定する場合
const mapObj = new Map([['key1',  'value1'], ['key2', 'value2']])

初期値は、キーと値のペア(['key', 'value'])の配列を渡すことで設定することができる。

要素の追加

Map.prototype.set(key, value)key に対する value を Mapオブジェクトに追加することができる。同じ key を追加した場合は、値が上書きされる。

mapObj.set('key3', 'value3')

// 複数追加したい場合、メソッドチェーンを利用する
mapObj.set('key3', 'value3')
     .set('key4', 'value4')

要素の取得

Map.prototype.get(key) key を指定して、値を取得することができる。

const output = mapObj.get('key3')
console.log(output)  // value3

要素の削除

Map.prototype.delete(key) key を指定して、削除することができる。

mapObj.delete('key3')
console.log(mapObj.get('key3'))  // undefined

反復処理

以下の2つのパターンがある。

  1. Map.prototype.forEach() を使う場合
  2. 反復可能オブジェクト(Iterator)を使う場合
    • Map.prototype.entries() : [key, value]の配列を挿入順で返す
    • Map.prototype.keys() : 各要素の key を挿入順で返す
    • Map.prototype.values() : 各要素の value を挿入順で返す
mapObj.forEach((value, key) => {
  console.log(key + ' = ' + value)
})

for (let [key, value] of mapObj.entries()) {
  console.log(key + ' = ' + value)
}

その他の便利メソッド

map-like に関して

これまで、Map オブジェクトをみてきたが、反復可能オブジェクト(Iterator)は生成コストがかかり、パフォーマンスに影響してくることが言われているらしい。

そこで、反復可能オブジェクト(Iterator)ではなく、配列を返すのみのMapのようなオブジェクトが生成できる、map-like というモジュールがある。

github.com

もしパフォーマンスを気にされる場合は、こちらを使うことも検討してみてはどうだろうか。(ちなみに、今回のプロジェクトではこちらを使っている。)

まとめ

Map オブジェクトに関して、整理を行った。キーと値のペアを頻繁に追加したり削除したりする場合は、Objectよりも、Map のほうが最適とのことだ。

それでは、ステキな開発ライフを。