概要:このチュートリアルでは、JavaScriptの配列メソッド`reduce()`と`reduceRight()`を使用して、配列を1つの値に縮約する方法を学習します。
JavaScript配列のreduce()メソッドの紹介
次のような数値の配列があるとします。
let numbers = [1, 2, 3];
Code language: JavaScript (javascript)
そして、配列の要素の合計を計算したいとします。
通常、次の例に示すように、`for`ループを使用して要素を反復処理し、それらを合計します。
let numbers = [1, 2, 3];
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
console.log(sum);
Code language: JavaScript (javascript)
出力
6
スクリプトはシンプルで分かりやすいです。
- まず、3つの数値1、2、3の配列を宣言します。
- 次に、`sum`変数を宣言し、その値をゼロに設定します。
- 3番目に、`for`ループで、`numbers`配列の要素を`sum`変数に足し合わせます。ループの後、`sum`変数の値は6になります。
私たちが行ったのは、配列を1つの値に**縮約**することでした。
`Array.prototype`を使用すると、次のように`reduce()`メソッドを使用して配列を単一の値に縮約できます。
let numbers = [1, 2, 3];
let sum = numbers.reduce(function (previousValue, currentValue) {
return previousValue + currentValue;
});
console.log(sum);
Code language: JavaScript (javascript)
とてもシンプルですよね?
`reduce()`メソッドを詳しく見てみましょう。
JavaScript配列のreduce()メソッドの詳細
以下は、`reduce()`メソッドの構文を示しています。
array.reduce(callbackFn [, initialValue])
Code language: CSS (css)
`reduce()`メソッドは2つの引数を取ります。
- コールバック関数 `callbackFn`。この関数は、多くの場合、リデューサーと呼ばれます。
- オプションの初期値。
`reduce()`メソッドは、配列のすべての要素に対して`callbackFn()`関数を呼び出します。
`reducer()`関数は、配列全体にわたって`callbackFn`を実行した結果の値を返します。
1) callbackFn()関数の引数
`callbackFn`関数は、次の構文を持ちます。
function callbackFn(previousValue, currentValue, currentIndex, array) { /**/}
Code language: PHP (php)
`callbackFn`関数は、4つの引数を取ります。
previousValue
`callbackFn`関数の前回の呼び出しから返された値。最初の呼び出しでは、`initialValue`を渡した場合、`previousValue`は`initialValue`になります。そうでない場合、その値は`array[0]`です。
currentValue
現在の配列要素の値。最初の呼び出しでは、`initialValue`を渡した場合は`array[0]`、そうでない場合は`array[1]`になります。
currentIndex
配列内の`currentValue`のインデックス。最初の呼び出しでは、`initialValue`を渡した場合は`0`、そうでない場合は`1`になります。
array
ループする配列。
2) initialValue引数
`initialValue`引数はオプションです。
`initialValue`を指定すると、`callbackFn`関数は、最初の呼び出しで`previousValue`を`initialValue`に、`currentValue`を配列の最初の要素に初期化します。
`initialValue`を**指定しない**場合、`callbackFn`関数は、`previousValue`を配列の最初の要素(`array[0]`)に、`currentValue`を配列の2番目の要素(`array[1]`)に初期化します。
次の表は、`reduce()`メソッドが`initialValue`引数に応じて初めて`callbackFn()`関数を実行する際のロジックを示しています。
initialValue | previousValue | currentValue |
---|---|---|
渡された場合 | initialValue | array[0] |
渡されない場合 | array[0] | array[1] |
次の例は、`initialValue`を100として`reduce()`関数がどのように進行するかを示しています。
let numbers = [1, 2, 3];
function getOrdinalSuffix(i) {
let j = i % 10, k = i % 100;
if (j == 1 && k != 11) return i + 'st';
if (j == 2 && k != 12) return i + 'nd';
if (j == 3 && k != 13) return i + 'rd';
return i + 'th';
}
let call = 1;
let sum = numbers.reduce(function (previousValue, currentValue, currentIndex, array) {
let result = previousValue + currentValue;
// show the 1st call, 2nd call, etc.
console.log(`${getOrdinalSuffix(call)} call`);
call++;
// show the immediate values
console.table({ previousValue, currentValue, currentIndex, result });
return result;
},100);
console.log(`Result: ${sum}`);
Code language: JavaScript (javascript)
出力
1st call
┌───────────────┬────────┐
│ (index) │ Values │
├───────────────┼────────┤
│ previousValue │ 100 │
│ currentValue │ 1 │
│ currentIndex │ 0 │
│ result │ 101 │
└───────────────┴────────┘
2nd call
┌───────────────┬────────┐
│ (index) │ Values │
├───────────────┼────────┤
│ previousValue │ 101 │
│ currentValue │ 2 │
│ currentIndex │ 1 │
│ result │ 103 │
└───────────────┴────────┘
3rd call
┌───────────────┬────────┐
│ (index) │ Values │
├───────────────┼────────┤
│ previousValue │ 103 │
│ currentValue │ 3 │
│ currentIndex │ 2 │
│ result │ 106 │
└───────────────┴────────┘
Result: 106
Code language: plaintext (plaintext)
また、以下は`initialValue`引数なしで`reduce()`メソッドを示しています。
1st call
┌───────────────┬────────┐
│ (index) │ Values │
├───────────────┼────────┤
│ previousValue │ 1 │
│ currentValue │ 2 │
│ currentIndex │ 1 │
│ result │ 3 │
└───────────────┴────────┘
2nd call
┌───────────────┬────────┐
│ (index) │ Values │
├───────────────┼────────┤
│ previousValue │ 3 │
│ currentValue │ 3 │
│ currentIndex │ 2 │
│ result │ 6 │
└───────────────┴────────┘
Result: 6
Code language: plaintext (plaintext)
JavaScript配列のreduce()メソッドのその他の例
製品オブジェクトの`shoppingCart`配列が次のように定義されているとします。
let shoppingCart = [
{
product: 'phone',
qty: 1,
price: 500,
},
{
product: 'Screen Protector',
qty: 1,
price: 10,
},
{
product: 'Memory Card',
qty: 2,
price: 20,
},
];
Code language: JavaScript (javascript)
ショッピングカート内の製品の合計金額を計算するには、次のように`reduce()`メソッドを使用できます。
let total = shoppingCart.reduce(function (previousValue, currentValue) {
return previousValue + currentValue.qty * currentValue.price;
}, 0);
Code language: JavaScript (javascript)
出力
550
この例では、`initialValue`引数を`reduce()`メソッドに渡していることに注意してください。
そうしないと、`reduce()`メソッドは`shoppingCart`配列の最初の要素(オブジェクト)を初期値として使用し、このオブジェクトに対して計算を実行します。そのため、正しくない結果が生じます。
JavaScript配列のreduceRight()メソッド
`reduceRight()`メソッドは、`reduce()`メソッドと同じように機能しますが、方向が逆になります。
`reduce()`メソッドは最初の要素から開始して最後の要素に向かって移動しますが、`reduceRight()`メソッドは最後の要素から開始して最初の要素に向かって逆方向に移動します。
次の例を参照してください。
let numbers = [1, 2, 3];
let sum = numbers.reduceRight(function (previousValue, currentValue) {
console.log({ previousValue, currentValue });
return previousValue + currentValue;
});
console.log(`Result:${sum}`);
Code language: JavaScript (javascript)
出力
{ previousValue: 3, currentValue: 2 }
{ previousValue: 5, currentValue: 1 }
Result:6
Code language: CSS (css)
次の図は、`reduce()`メソッドと`reduceRight()`メソッドの違いを示しています。
このチュートリアルでは、JavaScriptの配列`reduce()`メソッドと`reduceRight()`メソッドを使用して、配列を値に縮約する方法を学習しました。