【JS】更新頻度が高いデータ構造に最適なMap オブジェクトを試した
最近、あるプロジェクトで初めて Map オブジェクトを使うことになり、これまで使ったことがなかったので調べてみました。備忘録として残しておく。
Map オブジェクトとは
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つのパターンがある。
Map.prototype.forEach()
を使う場合- 反復可能オブジェクト(Iterator)を使う場合
mapObj.forEach((value, key) => { console.log(key + ' = ' + value) }) for (let [key, value] of mapObj.entries()) { console.log(key + ' = ' + value) }
その他の便利メソッド
- すべての要素を削除する: Map.prototype.clear()
- Keyの存在確認: Map.prototype.has(key)
map-like に関して
これまで、Map オブジェクトをみてきたが、反復可能オブジェクト(Iterator)は生成コストがかかり、パフォーマンスに影響してくることが言われているらしい。
そこで、反復可能オブジェクト(Iterator)ではなく、配列を返すのみのMapのようなオブジェクトが生成できる、map-like というモジュールがある。
もしパフォーマンスを気にされる場合は、こちらを使うことも検討してみてはどうだろうか。(ちなみに、今回のプロジェクトではこちらを使っている。)
まとめ
Map オブジェクトに関して、整理を行った。キーと値のペアを頻繁に追加したり削除したりする場合は、Objectよりも、Map のほうが最適とのことだ。
それでは、ステキな開発ライフを。