【JavaScript】reduceメソッドとは何か?第1, 第2, 第3, 第4引数の意味や初期値の設定方法を実例で解説(初心者向け、わかりやすい)

javascript-prograshi(プロぐらし)-kv JavaScript
記事内に広告が含まれていることがあります。

reduceメソッドとは何か?

reduceメソッドとは、配列の要素を一つずつ取り出し、指定した処理を行っていき、最終的に一つの値を返す関数です。

例えば、配列の中に入っている数値を全て足し上げるといった四則演算をすることができます。

reduceとは「減らす」という意味の英語です。

配列に含まれている要素を一つ一つ処理して、最終的に一つの結果のみを返すのでreducdという名前がついています。


reduceメソッドの基本形

reduceメソッドは次のような使い方をします。

array.reduce( ( 引数1, 引数2, 引数3m 引数4 ), 初期値  => 処理 )

指定した配列やreduceの途中の処理結果など、どのデータを使いたいかによって指定する引数の数が異なります。

最大で4つの引数をとります。それぞれの引数には次の値が入ります。

引数内容
第1引数処理前の値(直前の処理結果)
第2引数現在の要素の値
第3引数現在の要素のインデックス番号
第4引数元の配列
point
  • reduceメソッドで最終的に返るのは、第1引数に対して、最後の処理を実行した結果です。
  • 第1引数は処理結果が入るので蓄積を意味する「accumulate」を省略した「acc」がよく使われています。
  • 第2引数は現在の要素が入るので、要素を意味する「element」を省略した「elem」や「e」がよく使われています。


reduceメソッドの注意点

reduceメソッドを使うには、初回の処理を行うときなど、各引数に何が渡されているかを理解することが非常に重要です。

初回の処理は、前回の処理結果に0番目の要素が入った状態から始まる

初回の処理におていは、配列の最初の要素の値が入ります。それ以降は、直前の処理結果が入ります。

このため、第2引数である「現在の要素」には「1番目の要素」が入り、第3引数の「インデックス番号」は「1」から始まります。


for文で処理が回るのは、配列の数引く1

初回の処理の時点で「現在の要素」が1番目の要素(2つ目の要素)になるため、処理が実行される回数は、「配列の要素の数 – 1」となります。


初期値を指定できる

初期値を指定することで、配列の要素の数だけ処理を実行することもできます。

初期値を使用する場合は、引数と処理をカッコで囲んで、その横にカンマで初期値を記載し、全体をカッコで囲みます。

array.reduce( ( ( 引数1, 引数2, 引数3m 引数4 ), 初期値  => 処理 ), 初期値 )

初期値を使った実例は後述します。

実例

例えば、以下のように[0, 10, 20, 30]という配列「arr」があるとします。これに対してreduceメソッドを使い第1~第4引数までを出力してみます。

arr = [0, 10, 20, 30]

arr.reduce( ( a, b, c, d  ) => console.log( a, b, c, d ) )
引数内容初回の処理2回目の処理3回目の処理
第1引数処理前の値(直前の処理結果)0undefinedundefined
第2引数現在の要素の値102030
第3引数現在の要素のインデックス番号123
第4引数元の配列[0, 10, 20, 30][0, 10, 20, 30][0, 10, 20, 30]

初回の処理の時点で、直前の処理結果を表す第1引数の値が「0」、現在の要素を表す第2引数の値が「10」になっていることに注意してください。

なお、上記のreduceの処理では、四則演算などの処理を何も行っていないので、2回目の処理以降で第1引数は「undefined(未定義)」となります。


処理前の値(直前の処理結果)を使う処理

第1引数である、処理前の値(直前の処理結果)を使ってreduceを行う場合は以下のようになります。

array.reduce( 引数1 => 処理 )

アロー関数においては、引数が1つの場合、引数のカッコを省略できます。また、処理が1行で記述できるときは処理のカッコやreturnを省略することができます。

これは以下と同じです。

array.reduce( ( 引数1 )  => { return 処理 } )

functionを省略しない場合は以下のようになります。

array.reduce( function( 引数1 ){ return 処理 } )


実例(カッコやreturnを省略)

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

arr.reduce( a => a * 10 )

//処理結果
//10000
処理回数第1引数の値直線の処理内容
111
2101 * 10
310010 * 10
41000100 * 10

4回目の最後の処理で「1000*10 」を実行するため、結果は「10000」が返ります。


実例(カッコやreturnを省略しない場合)

引数にカッコをつけて、処理に{ } とreturnをつけると以下のようになります。

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

arr.reduce( ( a )  => { return a * 10 } )

//処理結果
//10000


実例(functionを省略しない場合)

functionを省略しない場合は以下のようになります。

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

arr.reduce( function( a ){ return a * 10 } )

//処理結果
//10000


現在の要素の値を使う場合

第2引数である、「現在の要素の値」を使ってreduceを行う場合は以下のようになります。

array.reduce( ( 引数1, 引数2 ) => 処理 )


実例

第2引数である、「現在の要素の値」を使うと、配列の中の要素を足し上げて合計値を算出することができます。

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

arr.reduce( ( a, b ) => a + b )

//処理結果
//15
処理回数第1引数の値第2引数の値処理の内容
1121 + 2
2333 + 3
3646 + 4
410510 + 5

4回目の最後の処理で「10 + 5」を実行するため、結果は「15」が返ります。


現在の要素のインデックス番号を使う場合

第3引数である、「現在の要素のインデックス番号」を使ってreduceを行う場合は以下のようになります。

array.reduce( ( 引数1, 引数2, 引数3 ) => 処理 )


実例

第3引数である、「現在の要素のインデックス番号」を使って、配列番号が偶数の要素のみ数値を足し上げる処理は以下のようになります。(※配列番号は0から始まります)

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

arr.reduce( ( a, b, c ) => {
    if ( c % 2 == 0  ){ return  a + b }
    else{ return a }
})

//処理結果
//9
処理回数第1引数の値第2引数の値第3引数の値ifの条件分岐処理の内容
1121false1
2332true1 + 3
3643false4
41054true4 + 5

4回目の最後の処理で「4 + 5」を実行するため、結果は「9」が返ります。

point

reduceの処理の中で条件分岐を使う場合は、条件に一致するときとしないときの両方の処理結果をreturnで返す必要があります。

returnしないと、直前の処理結果が「undefined」になってしまいます。

注意点

上記で配列番号が奇数の要素のみを足し上げたいときに、if ( c % 2 != 0 )としても上手くいきません。初期値に配列の1つ目の要素「1」が入ってしまうためです。

この場合は別途初期値を設定する必要があります(後述します)。


元の配列を使う場合

第4引数である、「元の配列」を使ってreduceを行う場合は以下のようになります。

array.reduce( ( 引数1, 引数2, 引数3, 引数4 ) => 処理 )


実例

第4引数である、「元の配列」を使って、配列の要素数よりも大きい数値のみ足し合わせる場合は以下のようになります(※初期値は2になっています)

arr = [2, 4, 6, 8, 10]

arr.reduce( ( a, b, c, d ) => {  
  if( d.length < b ){ return a + b }
  else{ return a }
})

//処理結果
//26

「d.length」=「[2, 4, 6, 8, 10].length」のため、結果は常に「5」になります。

処理回数第1引数の値第2引数の値第3引数の値ifの条件分岐処理の内容
1241false2
2262true2 + 6
3883true8 + 8
416104true16 + 10

4回目の最後の処理で「16 + 10」を実行するため、結果は「26」が返ります。

注意点

上記で配列番号が奇数の要素のみを足し上げたいときに、if ( c % 2 != 0 )としても上手くいきません。初期値に配列の1つ目の要素「1」が入ってしまうためです。

この場合は別途初期値を設定する必要があります(後述します)。


初期値を指定する

reduceメソッドではデフォルトでは初期値に配列の1つ目の要素が入った状態から処理が始まります。このため処理回数は「配列の数 – 1」となります。

reduceで初期値を設定すると、指定した初期値から処理を開始し、配列の要素の数だけ処理を繰り返すことができます。

array.reduce( ( ( 引数1, 引数2, 引数3m 引数4 ), 初期値  => 処理 ), 初期値 )

引数は必要に応じて減らしてください。

point
  • 初期値を使う場合は、引数と処理をカッコで囲む。(※カッコの数に注意)
  • 処理は配列の要素の数だけ繰り返される。


実例

例えば、配列の中の要素を一つ一つ足し上げるときに、初期値を100とすると、reduceの処理結果は「100 + 足し上げた数」となります。

arrs = [1,2,3,4]

arrs.reduce( ( ( a, b ) => a + b), 100 )

//処理結果
//110
処理回数第1引数の値第2引数の値処理の内容
11001100 + 1
21012101 + 2
31033103 + 3
41064106 + 4

4回目の最後の処理で「106 + 4」を実行するため、結果は「110」が返ります。


初期値の応用|配列の中の最大の要素の数を求める

初期値ありのreduceを活用すると、以下のように入れ子になった配列の中で最大の要素数を求めることができます。

arrs = [
  {a:[{x:1},{y:2}]}, 
  {a:[{x:1},{y:2},{z:3}]}, 
  {a:[{x:1},{y:2},{z:3},{w:4}]}
]

上記例の場合、1つ目のaの要素数は2つ、2つ目は3つ、 3つ目は4つになるので、4を返す処理にする場合は以下のようになります。

arr = [
  {a:[{x:1},{y:2}]}, 
  {a:[{x:1},{y:2},{z:3}]}, 
  {a:[{x:1},{y:2},{z:3},{w:4}]}
]

//最大の要素数を求める
ans = arr.reduce( ( acc, elem ) => {
    if( acc < elem.a.length ){
        return elem.a.length
    }else{
        return acc
    }
  }, 0)

console.log(ans)

//出力
4

初期値を0とし、各オブジェクトの要素数と直前の処理結果が入った変数「acc」を比較していきます。

要素数の方が大きければその数を「acc」に代入し、少なければ元の「acc」をそのまま返します。


参考

MDN公式 Array.prototype.reduce()

タイトルとURLをコピーしました