基礎からのJavaScript④ ~reduce()を用いた配列の計算(加算, 総乗, 平均)~
今回は、reduce()関数を用いた計算方法をいくつか紹介したいと思います。
reduce関数とは
配列とともに扱われるreduce()関数ですが、使用方法は以下の通りです。
配列.reduce(function(累積値, 要素) {
return (累積値に対する要素の処理内容)
})
reduce()関数を用いる前に
本記事での入力値は、数字間を半角スペースで区切った文字列(1 2 3 …)とします。
まず、半角スペースで区切られた文字列(lines[0])を分割して、配列(numbers)に格納するために以下の処理を行います。
var numbers = lines[0].split(' ').map(Number);
<コードの簡単な説明>
・lines[0]:1行目の入力値はlines[0]に格納されます。
・split:文字列.split( 区切り文字 )
・map(Number):入力値は文字列として認識されているので、計算を行うことができる状態にすべく、String(文字列)型→Number型に変換します。
それでは、reduce()関数を用いた計算方法を見ていきましょう。
配列の加算
【①reduce() & return を用いた方法】
// numbers : 1,2,3,4,5,6,7,8,9
var result_1 = numbers.reduce(function(a, b) {
return a + b; // a + b の結果が function(a, b) の a に入る。
})
console.log(`配列の加算①:${result_1}`);
-----------------------------------------------------------------------
出力結果:
配列の加算①:45
【②reduce() & ラムダ式 を用いた方法】
ラムダ式については、自分も十分に理解できていない部分があるのですが、
非ラムダ式:function (引数) { /* 処理内容 */ }
ラムダ式:(引数) => { /* 処理内容 */ }
という認識でよいと思います。上記で「return 以降」に記述していた処理内容を 「=> 以降」に記述していく感じですね。
var result_2 = numbers.reduce((a, b) => a + b);
console.log(`配列の加算②:${result_2}`)
-----------------------------------------------------------------------
出力結果:
配列の加算②:45
【③おまけ:for文を用いた方法】
加算のイメージが付きにくい方は、まず、for文でのループ処理を把握すると理解しやすいかもしれません。
var result_3 = 0;
for(var i = 0; i < numbers.length; i++){ // 配列数分、ループ処理を行う。
result_3 += numbers[i]; // i番目の要素をresult_3に加算する。
}
console.log(`配列の加算③:${result_3}`)
-----------------------------------------------------------------------
出力結果:
配列の加算③:45
配列の総乗
【①reduce() & return を用いた方法】
行っていることは、先ほどと大して変わりません。総乗の結果が大きくなる都合上、入力値を「1 2 3 4 5」と変更しています。
// numbers : 1,2,3,4,5
var result_1 = numbers.reduce(function(a, b) {
return a * b; // a * b の結果が function(a, b) の a に入る。
})
console.log(`配列の総乗①:${result_1}`);
-----------------------------------------------------------------------
出力結果:
配列の総乗①:120
【②reduce() & ラムダ式 を用いた方法】
var result_2 = numbers.reduce((a, b) => a * b);
console.log(`配列の総乗②:${result_2}`)
-----------------------------------------------------------------------
出力結果:
配列の総乗②:120
【③おまけ:for文を用いた方法】
これも同じく、総乗のイメージが付きにくい方は、まず、for文でのループ処理を把握すると理解しやすいかもしれません。ただし、先ほどの加算の時とは異なり、result_3の初期値を1としています。これは、0だと、入力値の数値を乗じても、結果が0となってしまうことを防ぐためです。
var result_3 = 1; // 初期値は0ではなく1。
for(var i = 0; i < numbers.length; i++){ // 配列数分、ループ処理を行う。
result_3 *= numbers[i]; // i番目の要素をresult_3に乗算する。
}
console.log(`配列の総乗③:${result_3}`)
-----------------------------------------------------------------------
出力結果:
配列の総乗③:120
配列の平均
【①reduce() & return を用いた方法】
行っていることは、先ほどと大して変わりません。結果の正当性が分かりやすいよう、こちらも入力値を「1 2 3 4 5」としています。
// numbers : 1,2,3,4,5
var result_1 = numbers.reduce(function(a, b) {
return a + b; // a + b の結果が function(a, b) の a に入る。
})
var average_1 = result_1 / numbers.length;
console.log(`配列の平均①:${average_1}`);
-----------------------------------------------------------------------
出力結果:
配列の平均①:3
【②reduce() & ラムダ式 を用いた方法】
var average_2 = numbers.reduce((a, b) => a * b) / numbers.length;
console.log(`配列の平均②:${average_2}`)
-----------------------------------------------------------------------
出力結果:
配列の平均②:3
【③おまけ:for文を用いた方法】
これも同じく、平均のイメージが付きにくい方は、まず、for文でのループ処理を把握すると理解しやすいかもしれません。result_3に全体の加算値を格納したのち、配列数分で割り、平均値を求めます。今回は加算のループ処理なので初期値は0で問題ありません。
var result_3 = 0; // 初期値は0。
for(var i = 0; i < numbers.length; i++){ // 配列数分、ループ処理を行う。
result_3 += numbers[i]; // i番目の要素をresult_3に加算する。
}
var average_3 = result_3 / numbers.length;
console.log(`配列の平均③:${average_3}`)
-----------------------------------------------------------------------
出力結果:
配列の平均③:3
なお、これだけ紹介してアレですが、可読性や処理パフォーマンスを踏まえると、「for文」のほうが良い説もありますね…。reduce(), for文の使い分けは意識したほうがよさそうです。
参考:JavaScriptでsplitを使って文字列を分割する方法【初心者向け】
参考:初心者でも分かるreduce()の使い方とサンプル例まとめ
参考:JavaScriptで学ぶラムダ式入門【初心者向けにわかりやすく解説】
参考:JavaScriptの配列のループ処理(for/map/reduce)の計測
参考:[JavaScript] reduceは可読性が悪くループで置き換え可能なので使うべきではない
著者:かわ