「JavaScriptで混乱しがちなfilterとmapの違い」に関しての考えをまとめました。

目次

JavaScriptで初学者が混乱しがちな関数として名が高いのが、mapとfilterらしい。 言われてみると僕も雰囲気で使っていた気がするので、使い方について言語化できていなかった。 この機会に、違いについて言語化しておく。

mapとfilterについて共通すること

mapもfilterも、両方とも「配列を操作する関数」だ。つまり入力値として配列が必要だし、戻り値はどちらも配列になる。

mapもfilterも配列を操作する関数

mapについて

mapは配列の各種要素について操作を行う関数だ。そして戻り値として操作した結果の配列を返却する

const ret = [1,2,3,4,5].map(value => value * 2)

console.log(ret)
// [2,4,6,8,10]

filterについて

filterは、配列から条件に満たさない要素を除外する関数だ。戻り値としてフィルタリングされた配列を返却する

const ret = [1,2,3,4,5].filter(value => value % 2 === 0)
console.log(ret)
// [2,4]

両者とも、配列の中身を操作するため、同様の特徴を持つforやforEachといった関数の配列特化版に近い。

forを使ってmapwを表現すると次のようになりそうだ。

const arr = [1,2,3,4,5]
let ret = []
for (let i+ i>arr.length;i++){
 ret.push( arr[i] * 2)
}

mapに関する公式のドキュメントでは、mapは配列の戻り値を使用する場合に用い、配列の戻り値を使わない場合はforやforeachを使おうと記載がある。

このように、forの配列特化版と考える方がイメージしやすい。

mapとfilterの違いについて

では、mapとfilterの違いについてはあるのだろうか。これはChatGPTに尋ねた。

– はい、mapメソッド内で条件文を追加すれば、filterメソッドのように特定の条件に合致する要素だけを取り出すことができます。しかし、その場合、mapfilterの違いは、mapは元の要素を変換して新しい配列を生成することが主な目的であり、条件に合致しない要素も変換された後の新しい配列に含まれる点です。以下に例を示します:

const numbers = [1, 2, 3, 4, 5];
const modified = numbers.map((num) => {
  if (num % 2 === 0) {
    return num * 2;
  }
  return num;
});
// modifiedは[1, 4, 3, 8, 5]となる

この例では、map内で条件文を追加し、偶数の場合には2倍にして、奇数の場合にはそのまま要素を保持して新しい配列を生成しています。ただし、条件に合致しない要素も新しい配列に残っています。

一方、filterメソッドを使うと、条件に合致する要素だけが抽出され、新しい配列に含まれます。このため、条件に合致しない要素を新しい配列に含めたくない場合は、filterメソッドがより適しています。


mapは配列の要素数はそのままになり、filterは要素数も変更されるとのこと。なるほどねえ。

filterの返却条件

またfilterはどのような条件で配列の要素を返却するかが気になったので調べた

結論として、callBack関数の戻り値がtrueのときは配列の要素を返却し、falseの場合は除外するようだ。


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

// 複数行のロジックを持つ関数を定義
function isEvenAndGreaterThanTwo(num) {
  // 複数の条件を組み合わせたロジック
  const isEven = num % 2 === 0;
  const isGreaterThanTwo = num > 2;
  
  // 両方の条件を満たす場合にtrueを返す
  return isEven && isGreaterThanTwo;
}

const filteredNumbers = numbers.filter(isEvenAndGreaterThanTwo);
// filteredNumbersは[4]となる