今回は、配列データを便利に操作する「map」メソッドについてと、連想配列のようなデータを操作できるMapオブジェクトを学習します。
map()の出来ることが多彩で学習方法が分からない
Mapオブジェクトについても学習しておきたい
このような内容も含めて、本記事では以下のような構成で解説していきます!
- 【基礎】そもそも「配列」とは?
- 【基礎】「map」の使い方
- 【実践】「map」のコールバック関数
- 【実践】類似メソッドについて
- 【実践】Mapオブジェクトの使い方
この記事で、map() / Mapオブジェクトをしっかり学習してスキルアップを目指していきましょう!
そもそも「配列」とは?
まずはそもそも「配列」とは何かについてきちんと理解しておきたい方は以下の記事を参考にしてください。「配列」の基本知識をきちんと身につけた上で今回のmapメソッドの解説を読み進めるとより理解度がアップしますので、「配列」の知識に不安のある方はぜひ確認しておいて下さい。
「map」の使い方
この章では、「map」メソッドの基本的な使い方について見ていきましょう! 主に、map()の構文や繰り返し処理の方法、およびforEachとの違いについて学んでいきいます。
「map」の構文について
それでは、「map」の基本的な使い方から学習を進めていきましょう!
まずは、一般的な構文を見てください。
var array = [ 配列データ ]; array.map( コールバック関数 );
「map」は配列データに使うメソッドであり、各要素1つずつに対して「コールバック関数」を実行し、その結果を新しい配列として返すことが出来るようになっています。つまり、この関数内に実行したい処理を書いておくことで、配列の各要素に対して好きな操作をすることが出来るというわけです!
配列を繰り返し処理する方法
基本的な機能に触れたところで、実際に「map」を使った事例を見てみましょう!
次のサンプルは、数値データを格納した配列に対して、「map」メソッドを使った例です。
var items = [1,2,3,4,5]; var result = items.map(function( value ) { //配列の各要素を2倍にする return value * 2; }); console.log( result );
出力結果は…
[2, 4, 6, 8, 10]
となります。
このサンプルでは、「1〜5」までの数値が格納された配列に対して、コールバック関数で各要素を2倍にする処理を実行しています。そのため、返り値として各要素が2倍になった配列を「result」に代入しているので、出力結果が2の倍数になっているのが分かります。
本来なら、「for文」や「while文」などを使ってループ処理を書くところですが、「map」を使うと非常にシンプルなプログラムで実現できるので便利ですね!
「forEach文」との違いについて!
ここまで「map」の基本的な使い方を見てきましたが、実は同じように配列を操作できる「forEach文」とよく似ているのに気がつくでしょう。
次のサンプルでは、まったく同じプログラムを「forEach」と「map」で試した例です。
//「forEach」で試した例 [1,2,3].forEach(function( value ) { console.log( value ); }); //「map」で試した例 [1,2,3].map(function( value ) { console.log( value ); });
出力結果は…
1 2 3
となります。このサンプルで分かるように、「forEach」「map」どちらでも得られる結果は同じです。
では、何が違うのかというと、最も大きなポイントは「返り値」があるかどうか…という点でしょう。つまり、「forEach」は単純に実行するだけのメソッドなのに対して、「map」は実行後の結果を配列データとして返してくれるという点が違うわけです。
次のサンプルで、具体的に見てみましょう!
var result = [1,2,3].forEach(function( value ) { return value * 2; }); console.log( result );
出力結果は…
undefined
となり、「forEach」は実行するだけで「返り値」は存在しないのが分かります。
今度は、「map」の例を見てみましょう!
var result = [1,2,3].map(function( value ) { return value * 2; }); console.log( result );
出力結果は…
[2, 4, 6]
となり、実行結果が「返り値」として配列データを取得できているのが分かりますね。
「map」のコールバック関数
ここからは、「コールバック関数」について、もう少し詳しく見ていきましょう!
これまでコールバック関数の引数は1つだけでしたが、実は3つの引数を取得することができます!
配列データ.map( function( value, index, array ) { });
これらの引数は、次のような意味があります。
- 「value」は、配列の値
- 「index」は、配列のインデックス番号
- 「array」は、現在処理している配列
上記内容を知っていると、さらに配列操作を便利にプログラミングできるようになります。
例えば、次のサンプルでは引数の「index」を使って、偶数の「Index番号」の時だけ値を2倍にしています。
var items = [1,2,3,4,5,6,7,8,9]; var result = items.map( function( value, index, array ) { //「value」が偶数の時だけ2倍にする if( value % 2 === 0 ) { return value * 2; } else { return value; } }); console.log( result );
出力結果は…
[1, 4, 3, 8, 5, 12, 7, 16, 9]
となり、偶数番目の値だけ2倍になっているのが分かりますね。このサンプル中の「IF文」の条件式を「index % 2 !== 0」に変更すれば、奇数番目の値だけを2倍にすることも出来るわけです。
また、「map」は元の配列データに一切変更を加えない特徴がありますが、3つ目の引数「array」を利用すれば、元のデータを変更することも可能です!
var items = [1,2,3,4,5,6,7,8,9]; items.map( function( value, index, array ) { //「array」と「index」を利用して、元の配列データを変更する array[index] = value * 2; }); //元の配列データを出力する console.log( items );
出力結果は…
[2, 4, 6, 8, 10, 12, 14, 16, 18]
となります。
このサンプルでは、引数の「index」「array」を利用して元の配列データにアクセスしているのが分かります。このように記述することで、現在処理している配列データを変更することが可能で、出力結果には値が2倍になった結果が表示されていますね。
第2引数のオブジェクトについて
これまで、「map」の第1引数に「コールバック関数」を指定していましたが、実は第2引数に任意の「オブジェクト」を指定することが出来ます!
var array = [ 配列データ ]; //第2引数にオブジェクトを指定 array.map( コールバック関数, オブジェクト );
これにより、指定の配列とオブジェクトを組み合わせて、さらに便利なプログラミングを実現することが出来るわけです。
例えば、次のサンプルでは食べ物を簡単なオブジェクトにした「foodList」を、「map」の第2引数に指定した例です。
var foodList = { 'オムライス': 450, '焼きそば': 500, 'お好み焼き': 600, '焼き飯': 400 }; 配列.map( function( value ) { //「this」がオブジェクトを参照する }, foodList ); //第2引数にオブジェクトを指定
このように、第2引数へ「foodList」と記述することで、コールバック関数内の「this」が「foodList」を参照できるようになるわけです。
次のサンプルでは、オブジェクトから任意のキーワードを指定して「価格」を返す例です。
var foodList = { 'オムライス': 450, '焼きそば': 500, 'お好み焼き': 600, '焼き飯': 400 }; //任意のキーワードを指定する var order = ['焼き飯', 'お好み焼き']; var result = order.map( function( value, index, array ) { //配列のキーワードを使ってオブジェクト内の値を取得する return this[value]; }, foodList ); console.log( result );
出力結果は…
[400, 600]
となります。
このサンプルでは、配列「order」でキーワードを設定し、そこからオブジェクトに登録されているキーワードと一致した「価格」を取得して配列として返しているのが分かります。
(出力結果は、それぞれ「焼き飯」「お好み焼き」の価格になっています)
このように、第2引数へオブジェクトを指定することで、「map」の活用範囲が大きく広がるので、ぜひ慣れておくようにしておきましょう!
類似メソッドについて
この章では、map()によく似た類似メソッドについて見ていきましょう! 主に、filter() / reduce()メソッドの使い方について学んでいきます。
filterの使い方
まずは、filter()メソッドについて見ていきましょう。filter()は、対象となるデータに特定の条件を与えて、それに該当するデータだけを抽出したいようなケースで役に立つメソッドです。
例えば、次のサンプル例を見てください!
var items = [5,2,7,8,3,1,6,8,4]; var result = items.filter( function( value ) { //5よりも小さい数値だけを抽出 return value < 5; }) console.log( result );
実行結果
[2, 3, 1, 4]
この例では、数値が格納された配列データに対してfilter()を使い、5よりも小さい数値だけを抽出しています。filter()メソッド内の関数にreturnで条件式の結果を返すことで、該当するデータだけを新規の配列に格納していくわけです。
このfilter()メソッドの基本的な使い方から応用技までを次の記事で体系的にまとめているので参考にしてみてください!
reduceの使い方
JavaScriptの配列ではmapメソッドと同じように配列の要素を操作するreduceというメソッドがあります。reduceメソッドを使うと、配列要素の隣同士を演算して要素の初めから終わりまで繰り返すことができます。
例えば、配列の要素を全部足して合計を求めるということができます。
var items = [1,2,3,4]; var result = items.reduce(function (previous, current, index, array) { return previous + current; }); console.log(result);
実行結果:
10
引数previousは、現在処理されている要素よりも一つ前の要素かinitialValue、もしくは一つ前の要素で実行された関数の結果のことを指します。引数currentは現在処理されている要素のことを指します。
Mapオブジェクトの使い方
この章では、ES2015(ES6)から導入されたMapオブジェクトについても合わせて解説しておきます。主に、Mapオブジェクトの作成・追加・取得・削除・繰り返し処理について学んでいきます。
Mapの宣言と要素の追加
まずは、Mapオブジェクトの作り方から見ていきましょう! Mapオブジェクトは、一般的に連想配列を作ることをイメージすると分かりやすいでしょう。
新規に作成(宣言)するにはnewを使ってインスタンスを作ることから始めます。
var map = new Map();
要素を追加するには「set()」メソッドを利用します。
map.set('name', '太郎');
この例では、「name」というキーに「太郎」という文字列の値を追加しています。
ちなみにですが、インスタンスを作成する際に初期値を次のように設定することも可能です。
new Map([['name', '太郎'], ['name', '花子']]);
要素の取得・削除方法
次に、作成した要素の取得および削除をする方法について見ていきましょう!
例えば、次のようなMapオブジェクトを作成してみます。
var map = new Map(); map.set('name', '太郎'); map.set('age', 30);
このMapオブジェクトに対して、「name」の値を取得するには「get()」を使って次のように記述します。
console.log(map.get('name'));
「get(‘name’)」と記述することで、Mapオブジェクトに格納されている「name」というキーを探して値を出力してくれるのです。
ちなみに、「size」を実行すると格納されている要素数を取得でき、「has()」を使うと任意のキーが存在するかを確認できます。
console.log(map.size); console.log(map.has('age'));
要素を削除するには「delete()」に削除したい要素のキーを指定するだけです
map.delete('name'); map.clear();
Mapオブジェクトに対して、「clear」を実行すると格納されているすべての要素が削除されます。
Mapオブジェクトの繰り返し処理
今度は、Mapオブジェクトに格納されている要素を繰り返し処理によって列挙する方法について見ていきましょう!
一般的にはfor-of文を使って繰り返し処理をするのが簡単なのですが、Mapオブジェクトには便利なプロパティが提供されています。例えば、「keys()」を使うと格納されている要素の「キー」をすべて取得することができるのです。
次のサンプル例を見てください!
for(var key of map.keys()) { console.log(key); }
この例では、keys()を使ってMapオブジェクトに格納されているキーを利用して繰り返し処理を実行しているのが分かります。これにより、Mapオブジェクトのキーがすべて列挙できるのです。
また、「values()」を利用すると今度はすべての「値」を取得することができます。
for(var val of map.values()) { console.log(val); }
これらの標準で提供されているプロパティを活用することで、より簡単にMapオブジェクトを制御できるので覚えておきましょう!
まとめ
今回は、配列を操作する「map」について学習しました!
ポイントだけ、もう一度おさらいしておきましょう。
- 「map」は配列の各要素に対して処理を実行できる!
- 「forEach」と違い、結果を新しい配列として返してくれる!
- コールバック関数には3つの引数を取得できる!
- 第2引数に任意のオブジェクトを指定できる!
- filterメソッド、reduceメソッドの使い方
- Map型オブジェクトで連想配列を扱う!
これらの内容を踏まえて、サンプルコードを見ながら自分でも実際にプログラムを書き、どのような結果が表示されるかを確認してみることをオススメします!