【JavaScript入門】リドュース

 「リドュース (reduce)」という言葉には「減らす」「単純化する」「まとめる」といった意味があります。JavaScript の配列メソッドである .reduce() は、まさにこれらの意味を体現した機能で、配列の複数要素を「1つの値」に集約するためによく使われます。合計値の算出など数値の処理だけでなく、オブジェクトの構築や文字列の結合など多岐にわたる応用が可能です。ここでは、リドュースの基本的な仕組みと、類似機能である .reduceRight() との違い、そして具体例について順番に紹介します。

1.リドュースの考え方

 JavaScript の .reduce() メソッドは、「配列を走査しながら、累積値を更新していき、最終的に単一の結果を得る」ための仕組みです。ユーザー定義のコールバック関数の戻り値がアキュムレータ(累積値)に蓄積されていき、処理がすべて終わった時点で一つの結果が返ります。

1.1.メソッドの構文

配列.reduce(コールバック関数(累積値, 現在値, インデックス, 配列全体) {}, 初期値);
  • 第1引数(必須):リドュースをどのようにおこなうかを定義する「コールバック関数」です。
    ・最低 2 つの引数(累積値, 現在値)は必須です。
    ・第3引数にインデックス、第4引数に配列自体を受け取ることも可能です。
  • 第2引数(任意):初期値を明示的に設定します。省略した場合は、配列の最初の要素が初期値となります。

1.2.関連するメソッド:.reduceRight()

  • .reduceRight() は、.reduce() と同様の動作をしますが、末尾から先頭に向かって要素を処理する点が大きく異なります。
  • 配列を逆から集計したい場合や、特定の順番で結果をまとめたい場合に便利です。

次の表に、この二つのメソッドをまとめています。

メソッド説明
.reduce(f)コールバック関数を用いたリドュース処理を先頭から順に実行。
.reduceRight(f)コールバック関数を用いたリドュース処理を末尾から順に実行。

2.サンプルコードで見るリドュース

2.1..reduce() の使用例

 以下は、配列内の数値を合計するサンプルです。初期値を指定しないバージョンと、初期値を指定するバージョンをそれぞれ確認します。

// 配列を準備
const numbers = [15, 5, 35, 20];

// 初期値を指定しない場合
console.log('- reduce1 -');
const total1 = numbers.reduce((acc, current, i) => {
  // acc が累積値、current が現在の要素、i がインデックス
  console.log(i, acc, current);
  return acc + current;
});
console.log(total1);

// 初期値を指定する場合
console.log('- reduce2 -');
const total2 = numbers.reduce((acc, current, i) => {
  console.log(i, acc, current);
  return acc + current;
}, 100); // ここで初期値を 100 に設定
console.log(total2);

※コンソール表示の中身は、変数 acccurrent に何が入っているかを理解するために出力しています。

2.2..reduceRight() の使用例

今度は .reduceRight() を用いて同じ配列の要素を末尾から合計します。

// 同じ配列を用意
const numbers = [15, 5, 35, 20];

// .reduceRight() で合計を求める
const totalReverse = numbers.reduceRight((acc, current, i) => {
  console.log(i, acc, current);
  return acc + current;
}, 0);
console.log(totalReverse);

.reduce() のときとは要素をたどる向きが逆になっている点が重要です。

 ここでは、実際にブラウザで結果を確認するための HTML を示します。サンプルではファイル名を reduce_example_app.html とし、中で JavaScript を直接記述しています。メッセージや変数名は自由に変更して構いません。

【reduce_example_app.html】

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>リドュース処理のサンプル</title>
</head>
<body>
  <h1>リドュースで合計値を計算する</h1>
  <div id="resultArea"></div>

  <script>
    // 数値配列を用意
    const values = [10, 20, 15, 5];

    // 初期値なしで合計を求める
    const sumNoInitial = values.reduce((acc, cur) => {
      return acc + cur;
    });

    // 初期値を 50 に設定して合計を求める
    const sumWithInitial = values.reduce((acc, cur) => {
      return acc + cur;
    }, 50);

    // それぞれの結果を文字列でまとめる
    const message = 
      `配列 [${values.join(', ')}] の合計(初期値なし)は「${sumNoInitial}」です。` + 
      `また、初期値を 50 とした場合の合計は「${sumWithInitial}」です。`;

    // 結果を表示
    const area = document.getElementById('resultArea');
    area.textContent = message;
  </script>
</body>
</html>

実行結果

解説

  • const values = [10, 20, 15, 5];
    配列に 4 つの数値を入れています。
  • reduce((acc, cur) => { ... }, 50);
    累積値 acc に現在値 cur を足し合わせながら進みます。最後に合計値が返ります。
    第二引数に初期値 (ここでは 50) を与えると、その数値から演算が始まります。
  • document.getElementById('resultArea').textContent = message;
    計算結果を HTML 上の <div> 要素に表示しています。

まとめ

  • リドュース (reduce) は配列の要素を順に処理して単一の値にまとめる強力なメソッドです。
  • .reduce().reduceRight() の違いは、処理が先頭からか末尾からかという点だけで、基本的な使い方は同じです。
  • 初期値を指定しない場合、配列の最初の要素が累積値の初期値になることをしっかり把握しておくと、思わぬバグを防げます。
  • 単純な数値の合計以外にも、文字列の結合やオブジェクトの生成など幅広い応用が可能です。自身の開発シーンに合わせて適切に利用してください。