IORI online School

JavaScript、html、css の無料学習サイト

【JavaScript 中級講座】配列の関数(forEach , map , filter)

[JavaScript 中級講座]配列の関数(forEach , map , filter)

本講座では、少し高度な配列の関数を学習する。 学習する関数は、forEach、map、filterである。

関数の引数について

これまで関数の定義方法と実行方法を、 サンプルプログラムで学習した。 すでに関数の利用方法については習得済みであると思う。 おさらいのためにサンプルを掲載する。

001<script>
002//配列を作成
003const colors = [ "red" , "green" ] ;
004
005//push()関数を利用
006colors.push ( "blue" ) ;
007
008//[red green blue]
009alert ( colors.join ( " " ) ) ;
010</script>

3行目で配列を作成して変数colorsに代入し、6行目で 配列のpush()関数を実行する。 push()関数の引数に文字列を渡すと、 配列の末尾に文字列が追加される。

配列に対してpush()関数を実行する時、引数に文字列を渡す。 引数に文字列を渡すと、配列の中で適切に処理を実行し、 配列の末尾に文字列が追加される。 これが、今まで学習した関数である。

今まで学習した関数は、引数に文字列や数字を渡した。
一方、引数に「関数」を渡すことができる。 それが、今回学習する関数である。

引数に関数を渡す
関数A (
   
関数B () {

      //処理b 

   }
) ;

難しいプログラムである。後ほどステップバイステップで関数の記述方法を学習する。 まず、軽く解説する。

まず、関数Aが存在して、関数Aを実行したい。 関数Aは引数に「関数」を受け取る。 ここが今までの関数とは異なる。 引数に「文字列」や「数値」を受け取るのではない。 では、関数Aを実行する。 関数Aを実行する時、引数に自分で作成した関数Bを渡す。 関数Bを受け取った関数Aは、関数Bを実行する。 関数Bを実行すると、処理bが実行する。
JavaScriptでは、引数に関数を受け取る関数がいくつも存在する。 今回学習する、forEach、map、filterの関数は、 引数に関数を受け取る。

配列のforEach()関数を利用する

配列のforEach()関数
配列の要素を全て取り出す時に利用する

配列のforEach()関数は、配列の要素を全て取り出す時に利用する。 いままで配列の要素を取り出す時、for文を利用した。 しかし実際は、ここでご紹介するforEach()関数を利用する場合が多い。

001<script>
002//配列を作成
003const colors = [ "red" , "green" ] ;
004
005//forEachを利用して配列の要素を取得
006colors.forEach (
007  function ( color , i , colors ) {
008    
009    alert ( i + ":" + color ) ;
010  }
011) ;
012</script>
プログラムを実行すると、「0:red」「1:green」と表示する。

まず、3行目で配列colorsを宣言して配列を代入する。 6行目で配列colorsのforEach()関数を実行する。 forEach()関数は配列が持っている関数で、 配列の要素を全て取り出す機能がある。

forEach()関数は、引数に関数を受け取る。 引数の関数は7行目から10行目までである。 しかし、これでは何をやっているか分からない。

ここで解説を一時中断する。 実際に、配列のforEach()関数を書いてみよう。

002//配列を作成
003const colors = [ "red" , "green" ] ;
004
005//forEachを利用して配列の要素を取得
006colors.forEach ( ) ;

6行目で変数colorsに対してforEach()関数を実行する。 まず、配列はforEach()関数を持っている。 6行目で、配列のforEach()関数を実行する。 ここまでは今まで学習した関数と同じである。 ここから異なる。 配列のforEach()関数は、引数に関数を受け取る。 では、引数の関数を記述しよう。

002//配列を作成
003const colors = [ "red" , "green" ] ;
004
005//forEachを利用して配列の要素を取得
006colors.forEach (
007
008
009
010
011) ;

forEach()関数の括弧の終わりを、エンターキーで下の方へ移動させる。 forEach()関数の引数の括弧は、6行目から11行目までである。 6行目から11行目の括弧の中に、forEach()関数の引数に渡す関数を記述する。

002//配列を作成
003const colors = [ "red" , "green" ] ;
004
005//forEachを利用して配列の要素を取得
006colors.forEach (
007
008  function ( color , i , colors ) {
009    //処理を書く
010  }
011) ;

8行目から10行目までが、引数の関数である。

引数に関数を渡す
関数A (
   
関数B () {

      //処理b 

   }
) ;

8行目から10行目までが、関数Bに相当する。 forEach()関数を実行すると、ここで渡した関数が実行する。

第一引数 color 配列の値
第二引数 i 実行回数
第三引数 colors 配列

forEach()関数を実行すると、配列の要素の数だけ、 引数で渡した関数(関数B)が実行する。 配列の要素数が「2」の場合、引数の関数は「2」回実行する。 引数の関数が実行する時、3つの引数が渡される。 今ここで解説するよりも、具体的な値を当てはめて学習しよう。

002//配列を作成
003const colors = [ "red" , "green" ] ;
004
005//forEachを利用して配列の要素を取得
006colors.forEach (
007  function ( color , i , colors ) {
008    
009    alert ( i + ":" + color ) ;
010  }
011) ;

6行目で配列のforEach()関数を実行する。 関数を実行すると、引数で渡した関数が配列の要素数、つまり「2」回実行する。 1回目に関数が実行する時、 引数にインデックス「0」の要素、「0」、配列が渡される。

003const colors = [ "red" , "green" ] ;
004
005//forEachを利用して配列の要素を取得
006colors.forEach (
007  function ( "red" , 0 , ["red","green"] ) {
008    
009    alert ( i + ":" + color ) ;
010  }
011) ;

7行目の関数に3つの引数が渡され実行される。
9行目が実行すると、「0:red」と表示する。 これが、1回目の処理である。では、2回目の処理を見る。

003const colors = [ "red" , "green" ] ;
004
005//forEachを利用して配列の要素を取得
006colors.forEach (
007  function ( "green" , 1 , ["red","green"] ) {
008    
009    alert ( i + ":" + color ) ;
010  }
011) ;

2回目の実行で、引数に「green」と「1」と「配列」が渡される。 9行目が実行すると、「1:green」と表示する。 さて、配列の要素は2つなので、以上でプログラムが終了する。

forEach()関数は、配列の全ての要素を取得する時に利用する関数である。 頻繁に利用する関数である。

配列のmap()関数を利用する

配列のmap()関数
配列の全ての要素に何か処理をして、 新しい要素を持つ新しい配列を作成する

配列が持っている、map()関数を学習する。 さきほど学習したforEach()関数は、 配列の全ての要素を取り出す処理をした。 一方map()関数は、 配列内の全ての要素に、ある処理 (例えば、全ての要素に10を加算する、 全ての要素に文字列を結合する等) をする場合、利用する。 全ての要素に処理を施した後、 その新しい要素を持った新しい配列が戻る。 つまりmap()関数は、 配列の要素を元に、新しい要素を持った配列を作る。

サンプルプログラムを見る。

001<script>
002//配列を作成
003const names = [ "IORI" , "iori" ] ;
004
005//mapを利用して配列の要素を処理
006const run = names.map (
007
008  function ( name , i , names ) {
009    
010    return "走る" + name ;
011  }
012) ;
013
014//[走るIORI,走るiori]
015alert ( run.join ( "," ) ) ;
016</script>
プログラムを実行すると、「走るIORI,走るiori」と表示する。

配列の全ての要素に文字列「走る」を文字列結合するプログラムである。

3行目で変数namesを宣言して配列を代入する。 6行目、配列namesのmap()関数を実行する。 配列のmap()関数は、配列の全ての要素に対して何か処理をして、 処理した後の 新しい要素が入った新しい配列を戻す。 6行目の変数runで、map()関数の戻り値(新しい配列)を受け取る。

map()関数の処理内容を解説する。 map()関数の引数に関数を渡すと、 配列の要素数だけ関数が実行する。 今回、8行目から11行目までが、引数の関数である。 配列の要素数は「2」なので、引数に渡した関数が2回実行する。

第一引数 name 配列の値
第二引数 i 実行回数
第三引数 names 配列

関数が実行するたびに、引数にこれらの値が渡される。 では、関数実行1回目の場面を見る。

002//配列を作成
003const names = [ "IORI" , "iori" ] ;
004
005//mapを利用して配列の要素を処理
006const run = names.map (
007
008  function ( "IORI" , 0 , names ) {
009    
010    return "走る" + name ;
011  }
012) ;

まず、8行目の引数nameに配列の最初の要素「IORI」が入り、引数iに「0」が入る。

map()関数は新しい要素をつくる関数である。 10行目に、returnキーワードがある。 新しい配列の要素にする値を、 returnキーワードの後ろに記述する

今回、文字列「走る」を要素nameに文字列結合して、戻す。 この値が新しい要素である。 引数の関数(8行目から11行目)が実行すると、 変数runに次の配列が入る。

インデックス
0 走るIORI

さて、配列namesの要素数は2である。もう一度関数が呼ばれる。 関数が呼ばれるとき、引数に「iori」と「1」が渡される。

002//配列を作成
003const names = [ "IORI" , "iori" ] ;
004
005//mapを利用して配列の要素を処理
006const run = names.map (
007
008  function ( "iori" , 1 , names ) {
009    
010    return "走る" + name ;
011  }
012) ;

10行目で新しい要素を作成する。 この関数の戻り値が新しい要素になる。 今回、文字列「走る」を変数nameの値「iori」に文字列結合する。

インデックス
0 走るIORI
1 走るiori

6行目の変数runに、このような配列が入る。 配列namesの全ての要素に対して処理を実行したので、 ここでmap()関数の処理は終了する。

002//配列を作成
003const names = [ "IORI" , "iori" ] ;
004
005//mapを利用して配列の要素を処理
006const run = names.map (
007
008  function ( name , i , names ) {
009    
010    return "走る" + name ;
011  }
012) ;
013
014//[走るIORI,走るiori]
015alert ( run.join ( "," ) ) ;

15行目で配列runの要素を表示すると、「走るIORI,走るiori」と表示する。

配列のfilter()関数を利用する

配列のfilter()関数を見る。 filter()関数は、条件に合う要素を配列の要素から取り出す時に利用する。 今回、配列に入った複数の数字から、「80」より大きな数字を取得する。

001<script>
002//配列を作成
003const points = [ 90 , 80 , 85 ] ;
004
005//filterを利用して要素を取得
006const res = points.filter (
007
008  function ( point , i , points ) {
009    
010    return point > 80 ;
011  }
012) ;
013
014//[90 85]
015alert ( res.join ( " " ) ) ;
016</script>
プログラムを実行すると、「90 85」と表示する。

配列が持っている、filter()関数を学習する。

配列のfilter()関数
配列の要素の中から、特定の条件を満たす要素を取得する

配列の要素から、ある条件に一致する要素を取り出したい時、 filter()関数を利用する。 filter()関数を実行すると、条件に一致した要素が入った 新しい配列が戻る

003const points = [ 90 , 80 , 85 ] ;
004
005//filterを利用して要素を取得
006const res = points.filter (
007
008  function ( point , i , points ) {
009    
010    return point > 80 ;
011  }
012) ;

プログラムを解説する。3行目で変数pointsを宣言して配列を代入する。 6行目で配列pointsに対して、filter()関数を実行する。 filter()関数の実行結果は、 条件に一致する要素が入った配列である。 6行目で変数resを宣言して、filter()関数の戻り値を受け取る。

さて、 filter()関数の引数に関数を渡す。 引数の関数は8行目から11行目までである。

003const points = [ 90 , 80 , 85 ] ;
004
005//filterを利用して要素を取得
006const res = points.filter (
007
008  function ( point , i , points ) {
009    
010    return point > 80 ;
011  }
012) ;

引数の関数は配列pointsの要素数だけ実行する。 関数が実行するたびに、引数に値が代入される。

第一引数 point 配列の値
第二引数 i 実行回数
第三引数 points 配列

引数の内容は今までの関数と同じである。 今回、配列pointsの要素数は「3」なので、引数の関数は3回実行する。

まず1回目を見る。

003const points = [ 90 , 80 , 85 ] ;
004
005//filterを利用して要素を取得
006const res = points.filter (
007
008  function ( 90 , 0 , points ) {
009    
010    return point > 80 ;
011  }
012) ;

関数の第一引数に「90」が入り、第二引数に「0」が入る。 filter()関数の機能は、 「条件に一致する要素を取り出し、取り出した要素を 新しい配列に代入して戻す」であった。 引数に渡した関数が「true」を戻すと、 その要素は新しい配列に代入される。 「false」を戻すと、その要素は無視され新しい配列に入らない。

今、処理中の要素は「90」である。 引数の関数で「true」を戻すと、新しい配列に「90」が入る。 「false」を戻すと、「90」は無視される。

008  function ( 90 , 0 , points ) {
009    
010    return point > 80 ;
011  }

変数pointは「90」である。「90」は「80」よりも大きいので、 戻り値は「true」である。つまり、新しい配列に「90」が入る。 この時点で、配列resは次のようになる。

インデックス
0 90

新しい配列resに、90が代入される。 では、2回目を見る。

003const points = [ 90 , 80 , 85 ] ;
004
005//filterを利用して要素を取得
006const res = points.filter (
007
008  function ( 80 , 1 , points ) {
009    
010    return point > 80 ;
011  }
012) ;

変数pointの値は「80」である。関数の戻り値に注目する。「80」は「80」よりも大きくは無いので、 「false」となる。つまり、配列の要素「80」は無視され、 新しい要素には入らない。

では、3回目の処理を見る。

003const points = [ 90 , 80 , 85 ] ;
004
005//filterを利用して要素を取得
006const res = points.filter (
007
008  function ( 85 , 2 , points ) {
009    
010    return point > 80 ;
011  }
012) ;

変数pointの値は「85」である。「80」よりも大きいので、 関数の戻り値は「true」となる。つまり、新しい配列に、要素の「80」が代入される。 以上で、全ての要素の処理が終了した。 6行目の変数resは、次のような状態である。

インデックス
0 90
1 85

新しい配列の要素は、全て「80」より大きな値である。 さて、サンプルプログラムの最後で変数resの値を表示する。 「90 85」と表示する。

まとめ

配列のforEach()関数
配列の要素を全て取り出す時に利用する
配列のmap()関数
配列の全ての要素に何か処理をして、 新しい要素を持つ新しい配列を作成する
配列のfilter()関数
配列の要素の中から、特定の条件を満たす要素を取得する