JavaScriptで用意されている配列メソッドには数多くの種類があり、当ブログでもこれまでさまざま配列メソッドを取り上げてきました。
配列メソッドの中でも、より実用的で広く利用されている反面、混同されがちなものが、forEach、map、filterメソッドです。

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

各メソッドの特徴

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

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

最大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);
});
// 2
// 4
// 6
// 8
// 10

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

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

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

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

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

// mapの場合
const mapResult = arr.map(value => {
  return value * 2;
});
console.log(mapResult); // [2, 4, 6, 8, 10]

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

つまり、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); //[5, 10, 15, 20, 25]

// filterの場合
const filterResult = arr.filter(value => {
  return value / 2;
});
console.log(filterResult); //[10, 20, 30, 40, 50]

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

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

別の例を見てみましょう。

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

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

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

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

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

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

まとめ

今回は、使い分けが難しいforEach、map、filterメソッドの違いについて解説しました。

それぞれの機能を検証していく中で、違いが見えてきたのではないでしょうか。

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

これらの内容を踏まえて、適切なメソッドを使い分けるようにしていきましょう。

配列メソッドの関連記事

配列メソッド -追加・削除・抜き取り・分割・結合
配列メソッド -検索
配列メソッド -並び替え
配列メソッド -繰り返し
配列メソッド -新しい配列
配列メソッド -forEach・map・filterの違い(当記事)