LoginSignup
27
31

More than 3 years have passed since last update.

【JavaScript】Mapを正しく使うためにまとめた情報

Last updated at Posted at 2020-02-27

はじめに

本記事は筆者がMapを使うために必要だと思った情報をまとめたものです。

Mapは連想配列を作成する為のものです。Mapが実装されるまではJavaScriptに連想配列が存在せず、代わりにObjectで対応していたケースが多いようですので、Objectと比較した内容をメインに記載していきます。

Mapとの比較が分かりやすいように、ObjectのProperty名はkeyとして扱っています。

連想配列に関わる処理をObjectからMapにする事で得られるメリット

  • Objectと違い、StringとSymbol以外の任意の値もkeyに設定できる
  • 要素数の取得や反復処理が比較的容易(最初からメソッドが用意されている)
  • 頻繁に要素を追加・削除する場合、Objectよりもパフォーマンスが優れるケースがある
  • prototypeが無い為、余計なデータが存在しない

参考: MDN - Map - オブジェクトとマップの比較

メソッド・実装方法

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...infor...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)等で配列に変換してmapforEachを使用する。

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]}`);
}
27
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
31