reduceメソッドとは何か?
reduceメソッドとは、配列の要素を一つずつ取り出し、指定した処理を行っていき、最終的に一つの値を返す関数です。
例えば、配列の中に入っている数値を全て足し上げるといった四則演算をすることができます。
reduceとは「減らす」という意味の英語です。
配列に含まれている要素を一つ一つ処理して、最終的に一つの結果のみを返すのでreducdという名前がついています。
reduceメソッドの基本形
reduceメソッドは次のような使い方をします。
array.reduce( ( 引数1, 引数2, 引数3m 引数4 ), 初期値 => 処理 )
指定した配列やreduceの途中の処理結果など、どのデータを使いたいかによって指定する引数の数が異なります。
最大で4つの引数をとります。それぞれの引数には次の値が入ります。
引数 | 内容 |
---|---|
第1引数 | 処理前の値(直前の処理結果) |
第2引数 | 現在の要素の値 |
第3引数 | 現在の要素のインデックス番号 |
第4引数 | 元の配列 |
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引数 | 処理前の値(直前の処理結果) | 0 | undefined | undefined |
第2引数 | 現在の要素の値 | 10 | 20 | 30 |
第3引数 | 現在の要素のインデックス番号 | 1 | 2 | 3 |
第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引数の値 | 直線の処理内容 |
---|---|---|
1 | 1 | 1 |
2 | 10 | 1 * 10 |
3 | 100 | 10 * 10 |
4 | 1000 | 100 * 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引数の値 | 処理の内容 |
---|---|---|---|
1 | 1 | 2 | 1 + 2 |
2 | 3 | 3 | 3 + 3 |
3 | 6 | 4 | 6 + 4 |
4 | 10 | 5 | 10 + 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の条件分岐 | 処理の内容 |
---|---|---|---|---|---|
1 | 1 | 2 | 1 | false | 1 |
2 | 3 | 3 | 2 | true | 1 + 3 |
3 | 6 | 4 | 3 | false | 4 |
4 | 10 | 5 | 4 | true | 4 + 5 |
4回目の最後の処理で「4 + 5」を実行するため、結果は「9」が返ります。
元の配列を使う場合
第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の条件分岐 | 処理の内容 |
---|---|---|---|---|---|
1 | 2 | 4 | 1 | false | 2 |
2 | 2 | 6 | 2 | true | 2 + 6 |
3 | 8 | 8 | 3 | true | 8 + 8 |
4 | 16 | 10 | 4 | true | 16 + 10 |
4回目の最後の処理で「16 + 10」を実行するため、結果は「26」が返ります。
初期値を指定する
reduceメソッドではデフォルトでは初期値に配列の1つ目の要素が入った状態から処理が始まります。このため処理回数は「配列の数 – 1」となります。
reduceで初期値を設定すると、指定した初期値から処理を開始し、配列の要素の数だけ処理を繰り返すことができます。
array.reduce( ( ( 引数1, 引数2, 引数3m 引数4 ), 初期値 => 処理 ), 初期値 )
引数は必要に応じて減らしてください。
実例
例えば、配列の中の要素を一つ一つ足し上げるときに、初期値を100とすると、reduceの処理結果は「100 + 足し上げた数」となります。
arrs = [1,2,3,4]
arrs.reduce( ( ( a, b ) => a + b), 100 )
//処理結果
//110
処理回数 | 第1引数の値 | 第2引数の値 | 処理の内容 |
---|---|---|---|
1 | 100 | 1 | 100 + 1 |
2 | 101 | 2 | 101 + 2 |
3 | 103 | 3 | 103 + 3 |
4 | 106 | 4 | 106 + 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」をそのまま返します。