ユーニックス総合研究所

  • home
  • archives
  • js-filter

JavaScriptのfilterの使い方: 配列をフィルタリングして新しい配列を作成する

  • 作成日: 2020-08-16
  • 更新日: 2023-12-28
  • カテゴリ: JavaScript

JavaScriptのfilterの使い方

JavaScriptの配列はfilterというメソッドを持っています。
このfilterを使うと配列内の要素を指定した条件でフィルタリングし、新しく配列を作成することができます。
配列から特定の値を取り除きたい! という時などに使えます。

↓は配列内から偶数を抽出するサンプルコードです。

const arr = [1, 2, 3, 4]  
const result = arr.filter(el => el % 2 === 0)  

console.log(result)  
// [ 2, 4 ]  

↑の場合はarrという配列をフィルターしています。
奇数の値を取り除いて偶数だけ残した配列を作成しています。

filterに渡すコールバック関数

filterの第1引数には関数を渡します。
関数はアロー関数か普通の関数のことです。

アロー関数の例↓。

const arr = [1, 2, 3, 4]  
const result = arr.filter(el => el % 2 !== 0)  

console.log(result)  
// [ 1, 3 ]  

アロー関数の場合はブレース({})を書かない場合はreturn文を省略して書くことができます。
↑の場合はreturn文を省略していますが実質的には値が関数内でreturnされています。

普通の関数の例↓。

const arr = [1, 2, 3, 4]  
const result = arr.filter(function (el) {  
    return el % 2 === 0  
})  

console.log(result)  
// [ 2, 4 ]  

普通の関数はアロー関数に比べると冗長なところがありますが、thisが関数内の参照になるなどの特徴があります。

filterは配列を先頭から走査しますが、要素を参照するごとにこのコールバック関数を呼び出します。

コールバック関数がtrueを返すと、filterは現在の要素を新しい配列に格納します。
falseを返した場合はfilterは新しい配列に要素を格納しません。

つまり、格納してほしい要素の条件を式で書いて、その結果をreturnすることで既存の配列をフィルタリングすることが出来るということになります。
アロー関数の場合はreturnを省略できるので非常にコンパクトに書くこともできます。

filterのコールバック関数の引数

filterに渡す第1引数のコールバック関数は、↓のような引数を取ります。
第1引数、第2引数、そして第3引数です。

  • 第1引数: 処理中の配列の要素
  • 第2引数: 現在の添え字
  • 第3引数: 走査中の配列

第2引数と第3引数については省略することもできます。
これらの引数は↓のような簡単なコードで確認することが出来ます。

const arr = [1, 2, 3, 4]  
const result = arr.filter((el, index, me) => {  
    console.log(`el: ${el}, index: ${index}, me: ${me}`)  
})  

出力結果↓。

el: 1, index: 0, me: 1,2,3,4  
el: 2, index: 1, me: 1,2,3,4  
el: 3, index: 2, me: 1,2,3,4  
el: 4, index: 3, me: 1,2,3,4  

添え字(index)に注目すると、filterが配列の先頭の要素から順に参照していっているのがわかります。
つまり普通のfor文で言うと↓のようなコードと同じです。

for (let i = 0; i < 4; i++) {  
    const el = arr[i]  
    console.log(el, i, arr)  
}  

filterのthisの変更

filterの第2引数にthisの参照先を渡すことが出来ます。
これを指定すると、filterを普通の関数で回したときの関数内で参照するthisの参照先を変更できます。

function CheckMe () {  
    this.sum = 0  
}  

const checkMe = new CheckMe()  
const arr = [1, 2, 3, 4]  
const result = arr.filter(function (el) {  
    this.sum += el  
}, checkMe)  

console.log(checkMe.sum)  
// 10  

↑のコードの場合、filterの第2引数にCheckMeのインスタンス、checkMeを渡しています。
こうすると、filterで呼ばれるコールバック関数内のthischeckMeを指すことになります。
this.sum += elの部分でcheckMe.sumに合計値を蓄えていくので、最終的な出力は10になります。

ちなみにfilterの第1引数に渡している関数をアロー関数にすると、↑のコードは意図しない結果になります。
アロー関数と普通の関数ではthisの参照先が異なるので注意しましょう。

filterの使用例

filterの使用例です。

偶数を抽出する

配列内から偶数を抽出し、新しい配列に格納するサンプルです。
コードな↓になります。

const arr = [1, 2, 3, 4]  
const result = arr.filter(el => el % 2 === 0)  

console.log(result)  
// [ 2, 4 ]  

el % 2」という演算は「elを2で割った余りを求める」という意味です。
たとえばelが3だった場合は2で割った余りは1になります。
この余りが0ということはelが2で割り切れるということです。

値が2で割り切れるというのはつまりその値が偶数であることを示しています。
逆に2で割り切れない場合は奇数になります。
面白いですよね。

奇数を抽出する

配列内から奇数を抽出し、新しい配列に格納するサンプルです。

const arr = [1, 2, 3, 4]  
const result = arr.filter(el => el % 2 !== 0)  

console.log(result)  
// [ 1, 3 ]  

2で割った余りが0でないならその値は奇数です。
よって「el % 2 !== 0」という演算の結果は奇数の場合はtrueになります。
ですので奇数の値だけがフィルターされます。

配列内から0を取り除く

配列内の0を取り除くサンプルです。

const arr = [1, 0, 2, 0, 3]  
const result = arr.filter(el => el !== 0)  

console.log(result)  
// [ 1, 2, 3 ]  

el !== 0」という式は「elが0でない」という意味です。
elが0でなければtrueになります。

特定の頭文字を持つ文字列

頭文字にCを持つ文字列を抽出するサンプルです。

const arr = ['Cat', 'Dog', 'Cute', 'Bird']  
const result = arr.filter(el => el[0] === 'C')  

console.log(result)  
// [ 'Cat', 'Cute' ]  

配列arrにはCatとかDogとかいろいろな文字列が入ってます。
文字列の先頭文字はel[0]で参照できます。
この文字がCなら結果はtrueになります。
結果として文字列の先頭がCになっている文字列だけが残ります。

問題

Q1: JavaScriptの配列のメソッドfilterの役割として適当なものを答えよ

  1. オブジェクトのフィルタリング
  2. 配列のフィルタリング
  3. オブジェクトの走査

Q2: filterの第1引数に渡せるものを答えよ

  1. 配列
  2. オブジェクト
  3. 関数

Q3: filterの第2引数を指定した場合、filterの第1引数に渡すべきものは何か答えよ

  1. 普通の関数
  2. アロー関数
  3. 配列

答え
Q1: 2
Q2: 3
Q3: 1