2023.08.10 [木] map()?new Map?
夏休みのような長期休暇は、普段なかなか調べられないことや学習などに時間を費やしたいところです。
最近では、JavaScriptのフレームワークを触わることも増え、mapなんちゃらと、よく見かけます。なんか新しいループの便利機能ぐらいに思ってました。
そうしたら、new Map
なんてのも見かけるようになって「あぁ、これは区別がつかなくなりそう」ということで、調べてみました。

Array.map()
array.map()は、JavaScriptの配列の要素を変換するための便利なメソッドの一つです。
このメソッドは元の配列の要素を1つずつ順番に取り出し、指定されたコールバック関数を適用して新しい要素を生成し、それらを含む新しい配列を返します。
参考:Array.prototype.map() - JavaScript | MDN
// 元の配列
const numbers = [1, 2, 3, 4, 5];
// 各要素を2倍に変換する新しい配列を生成
const doubledNumbers = numbers.map((num) => {
return num * 2;
});
console.log(doubledNumbers);
// 出力: [2, 4, 6, 8, 10]
map()メソッドは、配列イテレーターメソッドで、配列をループして、配列の要素を順番に指定した関数に渡す動きをします。イテレータ(Iterator)とはデータ構造の各要素に対して繰り返し処理によって要素を返す仕組みです。
3つの引数
第1引数として関数を受け取ります。この関数は、要素ごとに呼び出され、実行されるたびに、返された値が新しい配列に追加されます。
配列イテレーターメソッドの多くは、この関数に3つの引数が渡されます。
- 第1引数:配列の値
- 第2引数:配列要素のインデックス
- 第3引数:配列自身
const doubledNumbers = numbers.map((num,index,array) =>{ { return num * 2 + `、indexは${index}`+ `、配列${array}` }); //出力:["2、indexは0、配列1,2,3,4,5", "4、indexは1、配列1,2,3,4,5", "6、indexは2、配列1,2,3,4,5", "8、indexは3、配列1,2,3,4,5", "10、indexは4、配列1,2,3,4,5"]
map()メソッドの第2引数
第1引数には、関数を受け取りますが、第2引数を指定した場合、この第2引数がthisの対象となるキーワードとなります。
const city = { tokyo: "東京", nagoya: "名古屋", osaka: "大阪" }; const tomei =["tokyo","nagoya"] const doubledNumbers = tomei.map(function(name) { return this[name]; }, city); //オブジェクトcityがthisの対象、tomei配列をキーとして取得 //出力: ["東京", "名古屋"]
じつは、ES5の頃からあるメソッドで他にも便利な配列メソッドと一緒に紹介されていることが多いので、forEach()メソッド、filter()メソッド、reduce()メソッドも解説していきます。
array.forEach()
array.forEach()メソッドは、配列の各要素を順番にコールバック関数に渡し、各要素に対する操作を行います。要素の数だけコールバック関数が実行されます。
参考:Array.prototype.forEach() - JavaScript | MDN
const fruits = ['apple', 'banana', 'orange']; fruits.forEach((fruit, index, array) => { console.log(`${array}のindex${index}: ${fruit}`); }); //出力: //apple,banana,orangeのindex0: apple //apple,banana,orangeのindex1: banana //apple,banana,orangeのindex2: orange
array.filter()
array.filter()メソッドは、元の配列から条件を満たす要素だけを抽出して新しい配列を生成します。
filter()メソッドは元の配列の各要素を順番にコールバック関数に渡し、その関数がtrueを返す要素だけが新しい配列に含まれます。
参考:Array.prototype.filter() - JavaScript | MDN
const numbers = [1, 2, 3, 4, 5, 6]; const evenNumbers = numbers.filter(function(num) { return num % 2 === 0; }); console.log(evenNumbers); //出力: [2, 4, 6]
array.reduce()
array.reduce()メソッドは、配列の各要素を順番にコールバック関数に渡し、要素を集約していきます。
コールバック関数の戻り値が次のaccumulatorになり、最終的な集約結果が返されます。
reduce()メソッドの場合、第2引数は現在の要素となり、配列要素のインデックスは第3引数以降にズレます。
参考:Array.prototype.reduce() - JavaScript | MDN
const numbers = [1, 2, 3, 4, 5]; const sum = numbers.reduce((accumulator, currentValue, index) => { console.log(`accumulator: ${accumulator}, currentValue: ${currentValue}, index: ${index}`); return accumulator + currentValue; }, 0); console.log(sum); // 15 //出力: //accumulator: 0, currentValue: 1, index: 0 //accumulator: 1, currentValue: 2, index: 1 //accumulator: 3, currentValue: 3, index: 2 //accumulator: 6, currentValue: 4, index: 3 //accumulator: 10, currentValue: 5, index: 4 //15
new Map
Map
はキーと値のペアを格納するためのデータ構造です。
このようなデータを連想配列といい、文字列など非負整数以外のデータを添字に使用することができる配列のことを言います。
JavaScriptでは、オブジェクトがこの連想配列っぽい構造で、しばし「連想配列=オブジェクト」と紹介されてますが、添字に文字列とシンボルしか設定ができなかったり、値としてデータだけではなく、 関数(処理)も入れることができるため、本来の連想配列とは違う特性を持つため、JavaScriptではオブジェクトと呼び、連想配列という言葉を使ってきませんでした。
Mapはオブジェクトとは異なり、キーとして異なる型の値やオブジェクトも使用できます。これにより、連想配列や辞書のような構造を簡単に作成することができるようになりました。
また、Mapはキーの重複を許さず、順序を保持することが特徴です。
インスタンスの作成
new Map()
で新しいMapインスタンスを作成できます。
const myMap = new Map();
Mapオブジェクトの基本的な操作
キーと値の追加
set()
メソッドを使用してキーと値のペアを追加できます。
myMap.set('key1', 'value1'); myMap.set('key2', 'value2'); console.log(myMap) //出力: //key1: "value1" //key2: "value2"
キーを使用して値を取得
get()
メソッドを使用して特定のキーに対応する値を取得できます。
const output = myMap.get("key1"); console.log(output); //出力: //value1
キーの存在を確認
has()
メソッドを使用して指定したキーが存在するかを確認できます。
const exists = myMap.has('key1'); //出力: // true
キーと値の削除
delete()
メソッドを使用して特定のキーと値のペアを削除できます。
myMap.delete('key1'); console.log(myMap); //出力: // key2: "value2"
巻き上げは発生しますので、スコープに注意です。
サイズの取得
size
プロパティを使用してMapのサイズ(要素の数)を取得できます。
const size = myMap.size; console.log(size); //delete()で削除しているため //出力:1
for..ofを使用したMapのループ
for..ofを使用してMapの各キーと値のペアに対して処理を行えます。
const myMap = new Map(); myMap.set("key1", "value1"); myMap.set("key2", "value2"); for (const [key, value] of myMap) { console.log(`${key} = ${value}`); } // key1 = value1 // key2 = value2 for (const key of myMap.keys()) { console.log(key); } // key1 // key2 for (const value of myMap.values()) { console.log(value); } // value1 // value2 for (const [key, value] of myMap.entries()) { console.log(`${key} = ${value}`); } // key1 = value1 // key2 = value2
forEachで書くと
myMap.forEach((value, key) => { console.log(`${key}: ${value}`); });
for..of文とはkeyとvalueの順番が逆になるので要注意。
for..of文のほうがforEachと比べて、少し処理が早いのでfor..of文でOKです。
JavavaScriptでは、連想配列として利用する場合、Mapが良さそうです。

ES6(ES2015)が策定されてからすでに7年以上経っていますので、IE11以外のブラウザには実装済みです。
参考:ECMAScript 6 compatibility table
まとめ
array.map()
は、配列の便利な処理をするためのメソッド、new Map
は、連想配列などキー(key)とそれに対応する値(value)を対応させて保持するオブジェクトのことでした。
今後、使いどころはたくさんありそうです。
- 関連記事
-
- JavaScriptで要素を挿入する。 (2023/09/30)
- map()?new Map? (2023/08/10)
- ポートフォリオサイトを印刷用CSSでプリントする。 (2022/03/05)
- @useの使い方がわからない…ので (2022/02/12)
- display:contentsを使ってみたい。 (2021/09/30)
- jQueryだっていいじゃない。 (2021/03/09)
- TypeScriptってなんだ?! (2021/03/01)
- CSSの単位 (2020/09/03)
- JavaScriptのclassについて、書いてみた。 (2019/12/30)
- picture要素と、source要素と、srcset属性と (2018/10/02)