はじめに
本記事は筆者がMapを使うために必要だと思った情報をまとめたものです。
Mapは連想配列を作成する為のものです。Mapが実装されるまではJavaScriptに連想配列が存在せず、代わりにObjectで対応していたケースが多いようですので、Objectと比較した内容をメインに記載していきます。
Mapとの比較が分かりやすいように、ObjectのProperty名はkeyとして扱っています。
連想配列に関わる処理をObjectからMapにする事で得られるメリット
- Objectと違い、StringとSymbol以外の任意の値もkeyに設定できる
- 要素数の取得や反復処理が比較的容易(最初からメソッドが用意されている)
- 頻繁に要素を追加・削除する場合、Objectよりもパフォーマンスが優れるケースがある
- prototypeが無い為、余計なデータが存在しない
メソッド・実装方法
ObjectとMapのメソッド・実装対応表
Objectで実装していた事をMapではどのようにすればよいのかをまとめました。
次の様にMapをmap変数、Objectをobj変数にセットした前提で記載しています。
let obj = {};
let map = new Map();
目的 | Object | Map |
---|---|---|
データのクリアー | obj = {} | map.clear() |
データのセット | obj[key] = value obj.key = value |
map.set(key, value) |
keyによるデータの取得 | obj[key] obj.key |
map.get(key) |
keyによるデータの存在確認 | key in obj | map.has(key) |
keyによるデータの削除 | delete obj[key] | map.delete(key) |
要素数の取得 | Object.keys(obj).length | map.size |
全ての[key, value]を格納した配列の取得 | Object.entries(obj) | Array.from(map.entries()) |
全てのkeyを格納した配列の取得 | Object.keys(obj) | Array.from(map.keys()) |
全てのvalueを格納した配列の取得 | Object.values(obj) | Array.from(map.values()) |
その他のMapのメソッド
for...of
では必須のメソッドです。
目的 | Map |
---|---|
全ての[key, value]の配列を含むIteratorの取得 | map.entries() |
全てのkeyの配列を含むIteratorの取得 | map.keys() |
全てのvalueの配列を含むIteratorの取得 | map.values() |
反復処理
本記事で記載はしていますが、for...in
やfor...of
はESLintから怒られるので使わない方が良いかもしれません。
なるべくforEach
を使用した方が良いかもしれません。
詳しくはAirbnb JavaScriptスタイルガイド - Iterators and Generatorsが参考になりますので、ご覧ください。
Map
for...in
は使用できない(for...in
はObjectのプロパティに対して反復処理を行うものの為)
forEach
※forEach
内の関数の引数の順番に注意。
// 動作確認用のデータ作成
const map = new Map();
map.set(1, 100);
map.set(2, 200);
// keyとvalueを取得
map.forEach((value, key) => console.log(`key = ${key}, value = ${value}`));
for...of
// 動作確認用のデータ作成
const map = new Map();
map.set(1, 100);
map.set(2, 200);
// keyとvalueを取得
for (const [key, value] of map.entries()) {
console.log(`key = ${key}, value = ${value}`);
}
// keyを取得
for (const key of map.keys()) {
console.log(`key = ${key}`);
}
// valueを取得
for (const value of map.values()) {
console.log(`value = ${value}`);
}
Object
参考までにObjectについても記載。
for...of
は使用できない(Objectがiterableでない為)
Objectでfor...in
以外を使った反復処理を行う場合は、Object.entries(obj)
等で配列に変換してmap
やforEach
を使用する。
map
// 動作確認用のデータ作成
const obj = {
'1': 100,
'2': 200,
};
// keyとvalueを取得
Object.entries(obj).map((item, index) => console.log(`index = ${index}, key = ${item[0]}, value = ${item[1]}`));
// keyを取得
Object.keys(obj).map((key, index) => console.log(`index = ${index}, key = ${key}`));
// valueを取得
Object.values(obj).map((value, index) => console.log(`index = ${index}, value = ${value}`));
forEach
// 動作確認用のデータ作成
const obj = {
'1': 100,
'2': 200,
};
// keyとvalueを取得
// Object.entries(obj)で返ってくる値は[ [ '1', 100 ], [ '2', 200 ] ]
// indexが配列のインデックス、itemに配列内の値(今回だと最初が[ '1', 100 ])が格納される。
Object.entries(obj).forEach((item, index) => console.log(`index = ${index}, key = ${item[0]}, value = ${item[1]}`));
// forEachでkeyを取得
Object.keys(obj).forEach((key, index) => console.log(`index = ${index}, key = ${key}`));
// forEachでkeyを取得
Object.values(obj).forEach((value, index) => console.log(`index = ${index}, value = ${value}`));
for...in
// 動作確認用のデータ作成
const obj = {
'1': 100,
'2': 200,
};
// for...inでkeyとvalueを取得
for (item in obj) {
console.log(`key = ${item}, value = ${obj[item]}`);
}