実行環境 Node.js 15.2.1

公開日 2021年2月3日 JST

コード例の出力としてconsole.logを使用しています。

使用方法がわからない場合は以下のページを参照してからコード例を確認してください。

console.logの使用方法

reduce(Array、配列)

このページでは豊富な例を用いてJavaScript(js)のArrayオブジェクト(配列)のreduceの使い方を学ぶことができます。

JavaScript(js)のreduceはArrayオブジェクト(配列)のメソッドの1つです。

呼び出し元の配列の要素すべてに対してコールバック関数が実行され、コールバック関数の最終的な戻り値をreduceメソッドの戻り値として返します。
reduceメソッド自体は引数を最大で2つ、コールバック関数は最大で4つの引数を取ることができます。

TL;DR

基本

// 配列の各要素に対して第1引数のコールバック関数が実行され、コールバック関数の最終的な戻り値がreduceメソッドの戻り値となる
// 第1引数:コールバック関数で返される値 or 配列の最初の要素
// 第2引数:現在処理している配列の要素
const array1 = [0, 1, 2, 3];
const result1 = array1.reduce(function (accumulator, currentValue) {
  console.log(`accumulator: ${accumulator}, currentValue: ${currentValue}`);
  return accumulator + currentValue;
});
==> accumulator: 0, currentValue: 1
==> accumulator: 1, currentValue: 2
==> accumulator: 3, currentValue: 3
console.log(result1);
==> 6




// コールバック関数にアロー関数を指定
const array2 = ['js', 'JavaScript', 'TypeScript'];
const result2 = array2.reduce((accumulator, currentValue) => {
  return accumulator + ',' + currentValue;
});
console.log(result2);
==> js,JavaScript,TypeScript




// 空配列の場合はエラー
const array3 = [];
const result3 = array3.reduce((accumulator, currentValue) => accumulator + currentValue);
==> TypeError: Reduce of empty array with no initial value

コールバック関数の第1引数の初期値

// 「reduceメソッドの第2引数」を指定すると、「コールバック関数の最初の第1引数」を指定できる
const array1 = [1, 2, 3];
const initialValue1 = 100;
const return_value1 = array1.reduce(
  function (accumulator, currentValue) {
    console.log(`accumulator: ${accumulator}, currentValue: ${currentValue}`);
    return accumulator + currentValue;
  },
  initialValue1
);
==> accumulator: 100, currentValue: 1
==> accumulator: 101, currentValue: 2
==> accumulator: 103, currentValue: 3
console.log(return_value1);
==> 106




// 「reduceメソッドの第2引数」を指定しない場合、「コールバック関数の最初の第1引数」は配列の最初の要素
const array2 = [1, 2, 3];
const return_value2 = array2.reduce(
  function (accumulator, currentValue) {
    console.log(`accumulator: ${accumulator}, currentValue: ${currentValue}`);
    return accumulator + currentValue;
  }
  // 第2引数なし
);
==> accumulator: 1, currentValue: 2
==> accumulator: 3, currentValue: 3
console.log(return_value2);
==> 6




// 呼び出し元の配列が空、かつ、「reduceメソッドの第2引数」を指定した場合
const array3 = [];
const return_value3 = array3.reduce(
  (accumulator, currentValue) => accumulator + currentValue,
  100
);
console.log(return_value3);
==> 100




// 呼び出し元の配列が空、かつ、「reduceメソッドの第2引数」を指定しなかった場合
const array4 = [];
const return_value4 = array4.reduce(
  (accumulator, currentValue) => accumulator + currentValue
  // 第2引数なし
);
==> TypeError: Reduce of empty array with no initial value




// オブジェクトのプロパティ値の合計
const array5 = [{ subject: 'math', score: 80 }, { subject: 'science', score: 90 }];
const initialValue5 = 0;
const return_value5 = array5.reduce(
  (accumulator, currentValue) => accumulator + currentValue.score,
  initialValue5
);
console.log(return_value5);
==> 170

要素のインデックスの取得

// 「コールバック関数の第3引数」を指定して、「第2引数の配列内でのインデックス」を取得できる
const array1 = [100, 200, 300];
const return_value1 = array1.reduce(function (accumulator, currentValue, index) {
  console.log(`accumulator: ${accumulator}, currentValue: ${currentValue}, index: ${index}`);
  return accumulator + currentValue;
});
==> accumulator: 100, currentValue: 200, index: 1
==> accumulator: 300, currentValue: 300, index: 2
console.log(return_value1);
==> 600




// 「reduceメソッドの第2引数」で初期値を指定する場合のindexの変化
const array2 = [100, 200, 300];
const initialValue2 = 50;
const return_value2 = array2.reduce(
  function (accumulator, currentValue, index) {
    console.log(`accumulator: ${accumulator}, currentValue: ${currentValue}, index: ${index}`);
    return accumulator + currentValue;
  },
  initialValue2
);
==> accumulator: 50, currentValue: 100, index: 0
==> accumulator: 150, currentValue: 200, index: 1
==> accumulator: 350, currentValue: 300, index: 2
console.log(return_value2);
==> 650




// オブジェクトの生成
const array3 = ['js', 'JavaScript', 'TypeScript'];
const return_value3 = array3.reduce(
  (accumulator, currentValue, index) => {
    accumulator[index] = currentValue;
    return accumulator;
  },
  {}
);
console.log(return_value3);
==> { '0': 'js', '1': 'JavaScript', '2': 'TypeScript' }

呼び出し元配列の取得

// コールバック関数に第4引数を指定すると、呼び出し元の配列を得ることができる
const array1 = ['js', 'JavaScript', 'TypeScript'];
array1.reduce((accumulator, currentValue, index, arr) => {
  console.log(arr);
  return '';
});
==> [ 'js', 'JavaScript', 'TypeScript' ]
==> [ 'js', 'JavaScript', 'TypeScript' ]

解説

基本

reduceメソッドは呼び出し元の配列の各要素に対して、第1引数で指定したコールバック関数を実行し、 このコールバック関数の最終的な戻り値をreduceメソッドの戻り値として返します。

コールバック関数は第1引数と第2引数の指定が必須です。

第1引数は、最初のコールバック関数呼び出し時には呼び出し元配列の先頭の要素が代入され、 以降は前回のコールバック関数の戻り値・返り値が代入されます。
次項で説明するreduceメソッドの第2引数 が指定された場合、最初のコールバック関数呼び出し時の第1引数は、reduceメソッドの第2引数で与えられた値となります。

第2引数には、コールバック関数呼び出し時に処理されている呼び出し元配列の要素が代入されます。

// 配列の要素の合計値を求める
const array1 = [1, 2, 3];
const function1 = function (arg1, arg2) {
  console.log(`arg1: ${arg1}, arg2: ${arg2}`);
  return arg1 + arg2;
};
const return_value1 = array1.reduce(function1);
==> arg1: 1, arg2: 2
==> arg1: 3, arg2: 3
console.log(return_value1);
==> 6




// 配列の要素がすべてtrueかどうか調べる
const array2 = [true, true, false, true];
const return_value2 = array2.reduce((arg1, arg2) => arg1 === arg2);
console.log(return_value2);
==> false




// 空配列の場合はエラー
const array3 = [];
const return_value3 = array3.reduce((arg1, arg2) => arg1 + arg2);
==> TypeError: Reduce of empty array with no initial value

コールバック関数の第1引数の初期値

reduceメソッドは第2引数を任意で指定することができ、指定した場合、 その値はコールバック関数の第1引数の初期値として設定されます。

この第2引数を指定しない場合は、最初のコールバック関数呼び出し時の「コールバック関数の第1引数」は配列の先頭の要素に、「コールバック関数の第2引数」は次の要素になります。

しかし第2引数を指定することで、最初のコールバック関数呼び出し時の「コールバック関数の第1引数」を「reduceメソッドの第2引数」に、「コールバック関数の第2引数」は配列の先頭の要素とすることができます。

// 「reduceメソッドの第2引数」を指定した場合
const array1 = ['JavaScript', 'TypeScript'];
const initialValue = 'js';
const return_value1 = array1.reduce(
  function (arg1, arg2) {
    console.log(`arg1: ${arg1}, arg2: ${arg2}`);
    return arg1 + ',' + arg2;
  },
  initialValue
);
==> arg1: js, arg2: JavaScript
==> arg1: js,JavaScript, arg2: TypeScript
console.log(return_value1);
==> js,JavaScript,TypeScript




// 「reduceメソッドの第2引数」を指定しない場合
const array2 = ['JavaScript', 'TypeScript'];
const return_value2 = array2.reduce(
  function (arg1, arg2) {
    console.log(`arg1: ${arg1}, arg2: ${arg2}`);
    return arg1 + ',' + arg2;
  }
  // 第2引数なし
);
==> arg1: JavaScript, arg2: TypeScript
console.log(return_value2);
==> JavaScript,TypeScript




// 呼び出し元の配列が空、かつ、「reduceメソッドの第2引数」を指定した場合
const array3 = [];
const return_value3 = array3.reduce(
  (arg1, arg2) => arg1 + arg2,
  'Hello FooBarNinja'
);
console.log(return_value3);
==> Hello FooBarNinja




// 呼び出し元の配列が空、かつ、「reduceメソッドの第2引数」を指定しなかった場合
const array4 = [];
const return_value4 = array4.reduce(
  (arg1, arg2) => arg1 + arg2
  // 第2引数なし
);
==> TypeError: Reduce of empty array with no initial value

要素のインデックスの取得

コールバック関数の第3引数は任意で指定することができ、 指定した場合は現在のコールバック関数で処理されている要素(コールバック関数の第2引数)の配列内でのインデックスを取得することができます。

reduceメソッド自体の第2引数を指定した場合としていない場合で、最初に取得できるインデックスが異なります。 この点に注意して使用してください。

const array1 = [50, 60, 70];
const return_value1 = array1.reduce(function (arg1, arg2, arg3) {
  console.log(`arg1: ${arg1}, arg2: ${arg2}, arg3(index): ${arg3}`);
  return arg1 + arg2;
});
==> arg1: 50, arg2: 60, arg3(index): 1
==> arg1: 110, arg2: 70, arg3(index): 2
console.log(return_value1);
==> 180




// 「reduceメソッドの第2引数」で初期値を指定する場合
const array2 = [50, 60, 70];
const initialValue2 = 1000;
const return_value2 = array2.reduce(
  function (arg1, arg2, arg3) {
    console.log(`arg1: ${arg1}, arg2: ${arg2}, arg3(index): ${arg3}`);
    return arg1 + arg2;
  },
  initialValue2
);
==> arg1: 1000, arg2: 50, arg3(index): 0
==> arg1: 1050, arg2: 60, arg3(index): 1
==> arg1: 1110, arg2: 70, arg3(index): 2
console.log(return_value2);
==> 1180

呼び出し元配列の取得

コールバック関数の第4引数は任意で指定することができ、指定した場合は呼び出し元の配列を取得することができます。

// コールバック関数に第4引数を指定すると、呼び出し元の配列を得ることができる
const array1 = [0, 1, 2];
array1.reduce((arg1, arg2, arg3, arg4) => {
  console.log(arg4);
  return arg1;
});
==> [ 0, 1, 2 ]
==> [ 0, 1, 2 ]

1次情報

Array.prototype.reduce() - MDN web docs