JavaScriptで用意されている配列メソッドにはさまざまな種類があり、当サイトでもこれまで配列メソッドの使い方を解説してきました。
しかし、なんとなく理解はできたとしても、数あるメソッドを使い分けるには慣れが必要です。

配列メソッドの中でも、より実用的で広く使われている反面、類似メソッドであることから混同されがちなものとして、「forEach」「map」「filter」があります。

そこで今回は、それらのメソッドに焦点を当てて、どのような違いがあるのかを解説していきます。より適切なメソッドを使えるように理解を深めていきましょう。

各メソッドの特徴

forEach・map・filterメソッドの構文は共通して以下のようになります。

array.メソッド((value, index, array) => {
  実行したい処理;
});

forEach・map・filterメソッドは、最大3の引数を持つことができます。

  • 第1引数にvalue(要素の値)
  • 第2引数にindex(要素のインデックス番号)
  • 第3引数にarray(処理している配列)

ただし、すべての引数を使う必要はなく、主に第1引数、または第1と第2引数が使われることが多いです。

つぎに、各メソッドの特徴をかんたんに見ていきましょう。

forEachメソッド

繰り返し処理を行うために使われるメソッドです。
配列のすべての要素に対してコールバック関数の処理を行います。
単純に処理を実行するのみのため、返り値はありません。returnを記述すると、undefinedが返ります。

mapメソッド

繰り返し処理を行い、新しい配列を作るメソッドです。
forEachメソッドと同様、配列のすべての要素に対してコールバック関数の処理を行います。
異なるところは、実行結果が配列データとして返る点です。そのため、returnを記述することができます。

filterメソッド

条件に一致する要素を検索し、新しい配列を作るメソッドです。
mapメソッドと同様に、与えられたコールバック関数の処理を行い、新しい配列を生成するため、返り値を持つことができます。
異なるところは、条件に一致した要素のみを返すという点です。

つぎに、各メソッドを比較して、処理結果の違いを見ていきましょう。

forEachとmapの違い

繰り返し処理としてforEachとmapがよく似ていることに気が付くのではないでしょうか。どちらもすべての要素にコールバック関数で記述した処理を実行します。

同じプログラムをforEachとmapで検証してみます。

const arr = [1, 2, 3, 4, 5];

//forEachの場合
arr.forEach(value => {
  console.log(value * 2);
});

//mapの場合
arr.map(value => {
  console.log(value * 2)
});

実行結果

//2
//4
//6
//8
//10

foreach-map-filter

forEachもmapも得られる結果は同じです。

大きく異なる点は、返り値「return」を持つかどうかです。
今度は返り値を記述して比較してみましょう。

const arr = [1, 2, 3, 4, 5];

//forEachの場合
const forEachResult = arr.forEach(value => {
  return value * 2;
});
console.log(forEachResult);

//mapの場合
const mapResult = arr.map(value => {
  return value * 2;
});
console.log(mapResult);

実行結果

//undefined

//[2, 4, 6, 8, 10]

foreach-map-filter

forEachは、「undefined」となり、mapでは「2, 4, 6, 8, 10」という結果となりました。

これには、forEachは返り値を持たないのに対して、mapは返り値を持つという違いがあることが関係しています。

つまり、forEachは要素に対して単に処理を実行するメソッドである一方、mapは返り値として配列データを取得するメソッドになります。

mapとfilterの違い

mapとfilterも混同されやすいです。どちらも配列要素に対して与えられた関数を実行し、新しい配列を返します。

ここでも同じプログラムで比較してみましょう。

const arr = [10, 20, 30, 40, 50];

//mapの場合
const mapResult = arr.map(value => {
  return value / 2;
});
console.log(mapResult);

//filterの場合
const filterResult = arr.filter(value => {
  return value / 2;
});
console.log(filterResult);

実行結果

//[5, 10, 15, 20, 25]

//[10, 20, 30, 40, 50]

foreach-map-filter

どちらも新しい配列を返していますが、配列の中身が異なることに気がつきます。
mapは、要素を2で割った値を配列で返しているのに対して、filterは、要素の中から2で割れる要素のみを配列で返しています。

つまり、filterは、配列要素のうち条件にあった要素のみをフィルタリングし、それを配列として返しているのが特徴です。

1例だけだとmapとfilterの違いを理解するのは少し難しいため、別の例を見てみましょう。

const arr = [3, 13, 27, 30, 33];

//mapの場合
const mapResult = arr.map(value => {
  return value % 3;
});
console.log(mapResult);

//filterの場合
const filterResult = arr.filter(value => {
  return value % 3;
});
console.log(filterResult);

実行結果

//[0, 1, 0, 0, 0]

//[13]

foreach-map-filter

mapは、配列要素すべてに除算する関数を実行し、その計算結果を新しい配列で返しています。
filterは、配列要素の中で除算できる要素を探し、フィルタリングされた要素のみを配列で返しています。

mapは区別せずにすべての要素を返すのに対し、filterは条件内容によって要素を区別することが大きな違いです。

filterの実行結果では、条件に当てはまらない要素は省かれるため、元の要素の数よりも少なくなる場合があります。

まとめ

今回は使い分けが難しい「forEach」「map」「filter」の違いについて解説しました。

一見、どれも繰り返し処理ができる、もしくは、新しい配列を作るという印象でもありますが、それぞれの機能を検証していく中で、違いが見えてきたのではないでしょうか。

  • forEachは、すべての配列要素に対して処理を行い、その結果を取得する
  • mapは、すべての配列要素に対して処理を行い、その結果を配列として返す
  • filterは、条件に一致した配列要素をフィルタリングし、その要素のみの配列を返す

3つのメソッドは混同されがちでもありますが、特徴をおさえると上手く活用できるようになります。これらの内容を踏まえて、適切なメソッドを使い分けるようにしていきましょう。