君はJavaScriptのMapを知っているか?Mapの使い方・基本文法まとめ
こんにちは、AIQ株式会社のフロントエンドエンジニアのまさぴょんです!
今回は、JavaScriptのMapとは何か、Mapの使い方についてまとめて解説します。
JavaScriptのSet
に関しては、こちらの記事で解説しています。
JavaScriptのMapとは何か?
Map
とは、key
とvalue
のペアを紐づけて(Mappingして)格納することのできるコレクションタイプのData型の1つです。
ObjectとMapの違いとは?
Map
はObject
と同じように、key
とそれに紐づいたvalue
のデータの集まりです。
そんなMap
とObject
の違いは、どんな型のkey
も許可することです。
Object
では、key
名の設定には、制約がありますが、Map
では、どんな型のDataでもkey
として設定できます。
/** 1. Object の key名 の設定には、制約がある */
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
2000: 5000,
};
console.log("robotamaObject: ", robotamaObject);
// robotamaObject: {2000: 5000, name: 'ロボ玉', like: 'ひまわりの種', power: 1000, hamflag: true}
/** 2. Map の key名には、どんな型の Data も設定できる */
const robotamaMap = new Map();
robotamaMap.set("ロボ玉", typeof "ロボ玉");
robotamaMap.set(12, typeof 12);
robotamaMap.set(true, typeof true);
robotamaMap.set([1, 2, 3], typeof [1, 2, 3]);
robotamaMap.set(robotamaObject, typeof robotamaObject);
console.log("robotamaMap: ", robotamaMap);
// robotamaMap: Map(5) {'ロボ玉' => 'string', 12 => 'number', true => 'boolean', Array(3) => 'object', {…} => 'object'}
どんな時に、Mapを使用するのか? (Mapのユースケース)
それでは、Mapの使い所とは、どんな時でしょうか?
それは、key
に実際の変数Dataなどを使って、他のDataをMappingして管理したい場合などです。
(追記)
会社の先輩から教えていただき、ObjectとMapの使い分けのポイントとして、次のような点があるとのアドバイスをいただきました🌟
-
Map
の方が、追加、削除、取得(find)がObject
よりも早くパフォーマンスがいい。 -
Map
のkey
の順番は、挿入順がそのまま列挙順となることが保証されている。-
Object
の場合、key
の順番が列挙順で保証されているものと保証されていないものがある。 - ゆえに、
Object
で、列挙順に依存するコードを書くべきではない。
-
オブジェクト: 保証されることもあるが、混乱を招くので保証されないものとして扱うべきである。
Map: 挿入順。
引用元:[JavaScript] オブジェクト/Mapのキーの列挙順は保証されるのか
/** 1. DBから取得した UserDataList (ユーザーデータのリスト) */
const userList = [
{ id: 100, participant: "ロボたま", affiliation: "エンジニア" },
{ id: 101, participant: "まりぴょん", affiliation: "デザイナー" },
{ id: 102, participant: "白桃", affiliation: "営業部" },
];
/** 2. User id を key として、各Userごとの投稿・Data を管理する MapData */
const userPostListMap = new Map();
const userId_100 = userList[0].id;
const userId_101 = userList[1].id;
const userId_102 = userList[2].id;
/* 3-1. DBから取得した User id 100 の PostDataList (投稿データのリスト) */
const postList_100 = [
{ id: 100, content: "Next.js 14系の最新情報まとめ" },
{ id: 100, content: "Vue3・Nuxt3系の学習" },
{ id: 100, content: "Knex.jsとDataStore" },
{ id: 100, content: "Software設計講座" },
];
// userId_100 を key として DBから取得した投稿データのリストをSetする
userPostListMap.set(userId_100, postList_100);
/* 3-2. DBから取得した User id 101 の PostDataList (投稿データのリスト) */
const postList_101 = [
{ id: 101, content: "Figmaでのデザイン基礎講座" },
{ id: 101, content: "UI・UX向上のポイント" },
{ id: 101, content: "人を惹きつける、心地のいいデザイン" },
];
// userId_101 を key として DBから取得した投稿データのリストをSetする
userPostListMap.set(userId_101, postList_101);
/* 3-3. DBから取得した User id 102 の PostDataList (投稿データのリスト) */
const postList_102 = [
{ id: 102, content: "Sassの売り込み方" },
{ id: 102, content: "関係性の作り方" },
{ id: 102, content: "飲みニケーション講座" },
];
// userId_102 を key として DBから取得した投稿データのリストをSetする
userPostListMap.set(userId_102, postList_102);
console.log("userPostListMap: ", userPostListMap);
// userPostListMap: Map(3) {100 => Array(4), 101 => Array(3), 102 => Array(3)}
Mapの使い方・基本文法
ここからは、Map
の使い方・基本文法について解説していきます。
Map
の主なメソッドは次の通りです。
Mapの主なメソッド
-
const map = new Map()
– 新しいmap
インスタンスを作ります。 -
map.set(key, value)
–key
で、value
を格納します。 -
map.get(key)
– 指定されたkey
の値を返却します。map
に存在しないkey
の場合にはundefined
になります。 -
map.has(key)
–key
が存在する場合にtrue
を返します。そうでなければfalse
になります。 -
map.delete(key)
–key
で値を削除します。 -
map.clear()
–map
をクリアします。 -
map.size
– 現在のmap
インスタンスの要素の数です。
Mapの新規作成(初期インスタンスの作成)
Map
を新規作成する場合は、new Map()
の形で、Map
インスタンスを作成します。
また[[key, value]]
(多重配列)の形で 初期値を渡すことができます。
/** 1. 空の Map Instance が作成される */
const map = new Map();
console.log("map", map); // map Map(0)
/**
* 2. [[key, value]] (多重配列)の形で 初期値を渡すことができる
* => 複数ある場合は、カンマ(,)区切り
*/
const map2 = new Map([
["key1", "value1"],
["key2", "value2"],
]);
console.log("map2", map2);
// map2 Map(2) {'key1' => 'value1', 'key2' => 'value2'}
Mapの長さ・sizeを測る
map.size
で、Mapの長さ・sizeを測ることができます。
const map = new Map();
console.log("map", map); // map Map(0)
console.log("map.size", map.size); // 0
const map2 = new Map([
["key1", "value1"],
["key2", "value2"],
]);
console.log("map2", map2);
// map2 Map(2) {'key1' => 'value1', 'key2' => 'value2'}
console.log("map2.size", map2.size); // 2
Mapに値(value)を追加する
map.set(key, value)
の形で、Map
に値(value)を追加することができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const map = new Map();
// map.set(key, value) の形で、Mapに値(value)を追加する
map.set("robotama", robotamaObject);
Mapの値(value)を取得する
map.get(key)
の形で、Map
の値(value)を取得することができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const map = new Map();
// map.set(key, value) の形で、Mapに値(value)を追加する
map.set("robotama", robotamaObject);
// map.get(key) の形で、Mapに値(value)を追加する
const robotama = map.get("robotama");
console.log(robotama);
// {name: 'ロボ玉', like: 'ひまわりの種', power: 1000, hamflag: true}
Mapにkeyが存在するかどうかを確認する
map.has(key)
で、Map
がkey
が存在するかどうかを確認することができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const map = new Map();
// map.set(key, value) で、Mapに値(value)を追加する
map.set("robotama", robotamaObject);
// map.has(key) で、Mapが key が存在するかどうかを確認する
const isRobotama = map.has("robotama");
isRobotama ? console.log("あり") : console.log("なし");
Mapにセットしたvalueを削除する
map.delete(key)
で、Map
内の値(value)を削除することができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const map = new Map();
// map.set(key, value) で、Mapに値(value)を追加する
map.set("robotama", robotamaObject);
// map.delete(key) で、値(value)を削除します
map.delete("robotama");
console.log(map);
// Map(0) {size: 0}
Map内のDataをclearする(すべて削除する)
map.clear()
で、Map
内の値(value)をすべて削除することができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const piuiObject = {
name: "ピウイ",
like: "ミルク",
power: 5000,
hamflag: false,
};
const map = new Map([
["robotama", robotamaObject],
["piui", piuiObject],
]);
console.log(map);
// Map(2) {'robotama' => {…}, 'piui' => {…}}
// map.clear() で、value をすべて削除する
map.clear();
console.log(map);
// Map(0) {size: 0}
Mapでの繰り返し処理
Map
には、ループ処理でDataを取り出すための3つのメソッドがあります。
Mapのループ処理メソッド
-
map.forEach((value, key, map) => {})
–Map
から1つずつvalue
とkey
を取り出せます。 -
map.keys()
–key
に対するiterable
を返します。 -
map.values()
–value
に対するiterable
を返します。 -
map.entries()
–[key, value]
のiterable
を返します。
Mapから1つずつvalutとkeyを取り出すforEach
map.forEach((value, key, map) => {})
の形で、Map
から1つずつvalue
とkey
を取り出すことができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const piuiObject = {
name: "ピウイ",
like: "ミルク",
power: 5000,
hamflag: false,
};
const map = new Map();
map.set("robotama", robotamaObject).set("piui", piuiObject);
console.log("map: ", map);
// map: Map(2) {'robotama' => {…}, 'piui' => {…}}
map.forEach((val, key, map) => {
console.log("key: ", key);
console.log("val: ", val);
});
// Map(2) {'robotama' => {…}, 'piui' => {…}}
// key: robotama
// val: {name: 'ロボ玉', like: 'ひまわりの種', power: 1000, hamflag: true}
// key: piui
// val: {name: 'ピウイ', like: 'ミルク', power: 5000, hamflag: false}
Mapのkeyを繰り返し処理する
map.keys()
で、key
に対するiterable
(反復可能Data)を取得できます。
イテラブルなので、for of
文で取り出すことができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const piuiObject = {
name: "ピウイ",
like: "ミルク",
power: 5000,
hamflag: false,
};
const map = new Map();
map.set("robotama", robotamaObject).set("piui", piuiObject);
console.log("map: ", map);
// map: Map(2) {'robotama' => {…}, 'piui' => {…}}
const mapKeys = map.keys();
console.log("mapKeys: ", mapKeys);
// mapKeys: MapIterator {'robotama', 'piui'}
for (const key of mapKeys) {
console.log("key: ", key);
}
// key: robotama
// key: piui
Mapのvalueを繰り返し処理する
map.values()
で、value
に対するiterable
(反復可能Data)を取得できます。
イテラブルなので、for of
文で取り出すことができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const piuiObject = {
name: "ピウイ",
like: "ミルク",
power: 5000,
hamflag: false,
};
const map = new Map();
map.set("robotama", robotamaObject).set("piui", piuiObject);
console.log("map: ", map);
// map: Map(2) {'robotama' => {…}, 'piui' => {…}}
const mapValues = map.values();
console.log("mapValues: ", mapValues);
// mapValues: MapIterator {{…}, {…}}
for (const val of mapValues) {
console.log("val: ", val);
}
// val: {name: 'ロボ玉', like: 'ひまわりの種', power: 1000, hamflag: true}
// val: {name: 'ピウイ', like: 'ミルク', power: 5000, hamflag: false}
Mapのkeyとvalueのセット(entry)を繰り返し処理する
map.entries()
で、[key, value]
のiterable
(反復可能Data)を取得できます。
イテラブルなので、for of
文で取り出すことができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const piuiObject = {
name: "ピウイ",
like: "ミルク",
power: 5000,
hamflag: false,
};
const map = new Map();
map.set("robotama", robotamaObject).set("piui", piuiObject);
console.log("map: ", map);
// map: Map(2) {'robotama' => {…}, 'piui' => {…}}
const mapEntries = map.entries();
console.log("mapEntries: ", mapEntries);
// mapEntries: MapIterator {'robotama' => {…}, 'piui' => {…}}
for (const entry of mapEntries) {
console.log("entry: ", entry);
}
// entry: (2) ['robotama', {…}]
// entry: (2) ['piui', {…}]
Mapから配列を生成する
Array.from()
を使用することで、Mapから配列を生成することができます。
ちなみに、Map
をArray.from()
で配列にすると、[key, value]の配列になります。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const piuiObject = {
name: "ピウイ",
like: "ミルク",
power: 5000,
hamflag: false,
};
const map = new Map();
map.set("robotama", robotamaObject).set("piui", piuiObject);
console.log("map: ", map);
// map: Map(2) {'robotama' => {…}, 'piui' => {…}}
/** Map を Array.from() で配列にすると、[key, value]の配列になる */
const list = Array.from(map)
console.log('list', list);
// list (2) [Array(2), Array(2)]
// 0: ['robotama', {…}]
// 1: (2) ['piui', {…}]
MapからObjectを生成する
map.entries()
の実行結果(返り値)を利用して、Object.fromEntries(map.entries())
とすることで、MapからObjectを生成することができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const piuiObject = {
name: "ピウイ",
like: "ミルク",
power: 5000,
hamflag: false,
};
const map = new Map();
map.set("robotama", robotamaObject).set("piui", piuiObject);
console.log("map: ", map);
// map: Map(2) {'robotama' => {…}, 'piui' => {…}}
// Map から Object の作成
const object = Object.fromEntries(map.entries());
console.log("object: ", object);
// object: {robotama: {…}, piui: {…}}
Objectから、Mapを生成する
Object.entries(obj)
の実行結果(返り値)を利用して、new Map(Object.entries(obj))
とすることで、Objectから、Mapを生成することができます。
const robotamaObject = {
name: "ロボ玉",
like: "ひまわりの種",
power: 1000,
hamflag: true,
};
const piuiObject = {
name: "ピウイ",
like: "ミルク",
power: 5000,
hamflag: false,
};
const map = new Map();
map.set("robotama", robotamaObject).set("piui", piuiObject);
console.log("map: ", map);
// map: Map(2) {'robotama' => {…}, 'piui' => {…}}
// Object から、Map の生成
const robotamaMap = new Map(Object.entries(robotamaObject));
console.log("robotamaMap: ", robotamaMap);
// robotamaMap: Map(4) {'name' => 'ロボ玉', 'like' => 'ひまわりの種', 'power' => 1000, 'hamflag' => true}
const piuiMap = new Map(Object.entries(piuiObject));
console.log("piuiMap: ", piuiMap);
// piuiMap: Map(4) {'name' => 'ピウイ', 'like' => 'ミルク', 'power' => 5000, 'hamflag' => false}
まとめ
JavaScriptのコレクション管理には、Object
とArray
だけでなくMap
もあるので、ぜひMap
を活用して見てください。
個人で、Blogもやっています、よかったら見てみてください。
注意事項
この記事は、AIQ 株式会社の社員による個人の見解であり、所属する組織の公式見解ではありません。
求む、冒険者!
AIQ株式会社では、一緒に働いてくれるエンジニアを絶賛、募集しております🐱🐹✨
詳しくは、Wantedly (https://www.wantedly.com/companies/aiqlab)を見てみてください。
参考・引用
AIQ 株式会社 に所属するエンジニアが技術情報をお届けします。 ※ AIQ 株式会社 社員による個人の見解であり、所属する組織の公式見解ではありません。 Wantedly: wantedly.com/companies/aiqlab
Discussion
すごくわかりやすかったです
まじこじまさん、ありがとうございます、嬉しいです 🙌