Reactを勉強し始めた時にmap関数を初めて知った人も多いと思います。
自分もそうだったんですが、文法の意味が分かっていないので突然登場されてもイマイチ使い方が分かりません。
「mapって繰り返し処理ってことくらいは分かる」
「JavaScriptでforEachもあるけど、mapとは違うの?」
「自分でmapを使ってみるとなぜかコンソールにエラーがでる」
本日はそんな方に向けてmap関数の使い方、forEachとの違いを説明していきます。
また動画もあるので必要に応じて使ってください。
JavaScriptのmapは「配列の繰り返し」を行うもの
まず自分も最初分かってなかったんですが、mapは「配列」の繰り返しをしてくれる関数です。
適当に覚えていた自分は「オブジェクト」に対してもmapを使おうとしてエラーが出て丸1日ハマっていたこともあります。
mapは配列に使用できて、オブジェクトには使用できないことを何よりも最初に覚えましょう。
ちなみに使い方はこんな感じです。
const number = [1,2,3];
number.map((num) => {
num++;
console.log(num);
}) // 2,3,4と出力される
配列の中の数字をそれぞれ1ずつ加算したものをコンソールに出力してみました。
numberに1、2、3が入っていて、それぞれ順番にnumに入れて処理をしていく感じです。
ちなみにnumの部分について名前は自由ですが、「配列のなかの1個」という意味が何となく伝わるような単語にすることをおススメします。
JavaScriptにおけるmapとforEachの違い
さて繰り返し処理の代表的なものにforEachもあります。
先ほどの処理をforEachでも書き直すこともできて、forEachだと以下のような形になります。
const number = [1,2,3];
number.forEach((num) => {
num++;
console.log(num)
}) // 2,3,4と出力される
同じように加算された数字が表示されましたね。
mapとforEachの大きな違いは「配列を返すか?」になります。
先ほどの処理をもう一度mapで以下のように書いてみます。
const number = [1,2,3];
const numberMap = number.map((num) => {
num++;
console.log(num);
return num;
});
console.log(numberMap);
console.logの後にreturnでも配列の中身を出力するように追記しています。
またnumberMapという定数に関数の処理結果を格納して、numberMapもconsole.logで出力してみることにしました。
そうすることでconsole.logの分とは別で「配列になった数字」も出力されています。
最後の配列の部分が定数numberMapのものになります。
numberMapには[ 2, 3, 4 ]という形で配列が返されていることが分かりました。
さらにもう一度forEachの方でも同じようにしてみます。
const number = [1,2,3];
const numberForEach =number.forEach((num) => {
num++;
console.log(num);
return num;
})
console.log(numberForEach);
forEachを使った場合でも同じようにreturnを追記して、定数numberForEachに格納するように変更しています。
すると繰り返し処理内でのconsole.logは出力されていますが、定数numberForEach(return numの部分)についてはundefinedとなってしまっています。
このようにmapでは繰り返し処理の結果を「配列で返してくれる」ことが大きな特徴になります。
またmapについては「配列にのみ使用できる」といった特徴もあります。
const data = {id: "0001", name: "AAA", age: 20};
const result = data.map((num) => {
return num + 1;
});
console.log(result); // エラーになる
初学者の方だと配列とオブジェクトを間違えることがあるかと思いますので注意しましょう。
ちなみに配列の中の要素がオブジェクトになっている場合については問題ないです。
mapの便利な使い方
JavaScriptのmapは配列に対して繰り返し処理を行うわけですが、この特性を使うと便利な使い方があるので共有します。
const students = [
{
id: "0001",
name: "AAA",
age: 20,
},
{
id: "0002",
name: "BBB",
age: 19,
},
{
id: "0003",
name: "CCC",
age: 18,
},
];
const formatted = students.map((student) => ({
// キーは[]で囲うルール
[student.id]: student.name,
}));
console.log(formatted);
// [{"0001": "AAA"},{"0002": "BBB"},{"0003": "CCC"}]と出力される
配列studentsの要素の作り方を変えることができました、元の配列studentsをベースに新しい配列formattedを作ったわけです。
APIでデータを取得した際に自分のプログラム上で操作しやすい構成に変換したい場面で使うことができますね。
ちなみに上記のコードは以下のように書き換えることもできます。
const students = [
{
id: "0001",
name: "AAA",
age: 20,
},
{
id: "0002",
name: "BBB",
age: 19,
},
{
id: "0003",
name: "CCC",
age: 18,
},
];
// ここから修正
const reformatted = students.map(({ id, name }) => ({
[id]: name,
}));
console.log(reformatted);
mapの引数がオブジェクトになっていますね、いわゆる分割代入を行なっています。
「student.id」「student.name」など毎回studentと書くことを省略することができています。
JavaScriptの分割代入について初見の方は別の記事で解説していますのでご覧ください。