【JavaScript】配列を操作する方法!reduceメソッドの使い方!

この記事では配列を操作するメソッド『reduceメソッド』について、以下の内容をサンプルコードを用いて分かりやすく説明するように心掛けています。ご参考になれば幸いです。

  • reduceメソッドとは
  • reduceメソッドの構文
  • reduceメソッドの使い方
    • 配列の要素の合計を計算する
    • 配列の要素を結合する
    • 最大値・最小値を求める
    • オブジェクトの配列を一つのオブジェクトに変換する
    • ネストされた配列をフラットにする
  • reduceメソッドの特徴
    • 配列が空の場合にはエラーになる
    • 空の要素はスキップするが、値がundefinedの場合はスキップしない

reduceメソッドとは

reduceメソッドは、配列の隣り合う2つの要素に対して左から右へ関数を実行し、最終的に単一の値を生成するメソッドです。例えば、配列の中身を一つずつ足していって合計を求めることができます。

後ほどreduceメソッドの構文や使い方について詳しく説明しますが、まず以下に示す簡単なサンプルコードを見てみましょう。

const array = [1, 2, 3, 4, 5];
const sum = array.reduce(
  (accumulator, currentValue) => accumulator + currentValue
);
console.log(sum); // 15

このサンプルコードでは、配列arrayの要素の合計値を計算し、変数sumに格納しています。

reduceメソッドの構文

reduceメソッドの構文を以下に示します。

reduceメソッドの構文

array.reduce(callback [, initialValue])

arrayは処理対象の配列です。reduceメソッドの引数と返り値を以下に示します。

引数

  • callbackFn
    • 配列の各要素に対して実行される関数です。この関数は以下の引数を取ります。
    • accumulator
      • 前回のcallbackFnの呼び出し結果の値です。
      • 初回のcallbackFn実行時、initialValueが指定されていた場合はinitialValue、そうでない場合はarray[0]の値になります。
    • currentValue
      • 現在処理されている要素の値です。
      • 初回のcallbackFn実行時、initialValueが指定された場合はarray[0]、そうでない場合はarray[1]の値になります。
    • currentIndex(省略可能)
      • 現在処理されている要素のインデックスです。
      • 初回のcallbackFn実行時、initialValueが指定された場合は0、そうでない場合は1になります。
    • array(省略可能)
      • reduceが呼び出された処理対象の配列です。
  • initialValue(省略可能)
    • callbackFnが最初に呼び出された時にaccumulatorが初期化される値です。
    • initialValueが指定されている場合
      • 初回のcallbackFn実行時、accumulatorにはinitialValuecurrentValueには配列の最初の値array[0]が入ります。
    • initialValueが省略されている場合
      • 初回のcallbackFn実行時、accumulatorには配列の最初の値array[0]currentValueには配列の2番目の値array[1]が入ります。

返り値(戻り値)

  • reduceメソッドは配列全体にわたってコールバック関数を実行した結果の値を返します。

ではこれからサンプルコードを用いて詳しく説明します。

reduceメソッドの使い方

reduceメソッドについて、以下に示している使い方を順番に説明します。

  • 配列の要素の合計を計算する
  • 配列の要素を結合する
  • 最大値・最小値を求める
  • オブジェクトの配列を一つのオブジェクトに変換する
  • ネストされた配列をフラットにする

配列の要素の合計を計算する

reduceメソッドを使うと、配列の要素の合計を計算することができます。

以下のサンプルコードでは、配列arrayの各要素の合計値を求めています。

const array = [1, 2, 3];
const sum = array.reduce(
  (accumulator, currentValue, currentIndex) => accumulator + currentValue
);
console.log(sum); // 15

上記のサンプルコードでは説明を分かりやすくするためにcallbackFnの引数(array)とinitialValueを省略しています。コールバック関数callbackFnは 2回実行され、各回の引数の内容は以下のようになります。

callbackFn実行回数accumulatorcurrentValuecurrentIndexcallbackFnの返り値
1回目1213
2回目3326

callbackFn実行1回目のaccumulatorには、配列の1番目の要素である1が入り、currentValueには2番目の要素である2が入ります。callbackFnが実行されると、1 + 23が返されます。

callbackFn実行2回目のaccumulatorには、1つ前の要素で実行されたcallbackFnの返り値である3が入り、currentValueには3番目の要素である3が入ります。そしてcallbackFnが実行されると、3 + 36が返されます。

reduceメソッドの返り値は、callbackFn呼び出しの最後の返り値である6となります。

配列の要素を結合する

reduceメソッドは、配列の要素を結合して一つの文字列にすることもできます。

以下のサンプルコードでは、配列words内の各要素をスペースで結合して一つの文字列sentenceにしています。reduceメソッドは、最初の要素'Hello'を初期値とし、次の要素'World'を結合していきます。この処理をすべての要素に対して行うことで、最終的に'Hello World from JavaScript'が出力されます。

const words = ['Hello', 'World', 'from', 'JavaScript'];
const sentence = words.reduce(
  (accumulator, currentValue) => accumulator + ' ' + currentValue
);
console.log(sentence); // 'Hello World from JavaScript'

最大値・最小値を求める

reduceメソッドは、配列の要素から最大値・最小値を求めることもできます。

以下のサンプルコードでは、Math.maxを使用して配列numbersの最大値を求めています。具体的には、初期値として-Infinityを指定し、配列numbers内の各要素と比較して最大のものをaccumulatorに保持します。最終的に、配列numbersの各要素の最大値である8が出力されます。

const numbers = [5, 1, 8, 3, 2];
const max = numbers.reduce(
  (accumulator, currentValue) => Math.max(accumulator, currentValue),
  -Infinity
);
console.log(max); // 8

オブジェクトの配列を一つのオブジェクトに変換する

reduceメソッドは、オブジェクトの配列を一つのオブジェクトに変換することもできます。

以下のサンプルコードでは、配列people内の各オブジェクトをnameをキー、ageを値とする新しいオブジェクトpeopleByNameに変換しています。reduceメソッドを使用して、各人の名前と年齢を新しいオブジェクトのプロパティとして追加しています。最終的に{ Alice: 25, Bob: 30, Charlie: 35 }が出力されます。

const people = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 35 },
];
const peopleByName = people.reduce((accumulator, person) => {
  accumulator[person.name] = person.age;
  return accumulator;
}, {}); // 初期値を{}にしている
console.log(peopleByName); // { Alice: 25, Bob: 30, Charlie: 35 }

ネストされた配列をフラットにする

reduceメソッドは、ネストされた配列をフラットにすることもできます。

以下のサンプルコードでは、ネストされた配列nestedArrayを一つのフラットな配列flatArrayに変換しています。reduceメソッドを使用して、各サブ配列をaccumulatorに連結していきます。初期値として空の配列[]を指定し、全ての要素を結合することで[1, 2, 3, 4, 5]が出力されます。

const nestedArray = [[1, 2], [3, 4], [5]];
const flatArray = nestedArray.reduce(
  (accumulator, currentValue) => accumulator.concat(currentValue),
  []
);
console.log(flatArray); // [1, 2, 3, 4, 5]

reduceメソッドの特徴

reduceメソッドの特徴を以下に示します。

  • 配列が空の場合にはエラーになる
  • 空の要素はスキップするが、値がundefinedの場合はスキップしない

各特長について順番に説明します。

配列が空の場合にはエラーになる

配列が空で初期値が指定されていない場合、reduceメソッドはエラーを投げます。

以下のサンプルコードでは、空の配列emptyArrayに対して初期値を指定せずにreduceメソッドを実行しています。その結果、エラーTypeError: Reduce of empty array with no initial valueが投げられます。空の配列に対してreduceを使用する場合、初期値を指定することが重要です。

const emptyArray = [];
try {
  const result = emptyArray.reduce(
    (accumulator, currentValue) => accumulator + currentValue
  );
} catch (e) {
  console.error(e); // TypeError: Reduce of empty array with no initial value
}

空の要素はスキップするが、値が undefined の場合はスキップしない

reduceメソッドは、疎配列の欠落している要素はスキップしますが、値がundefinedの要素はスキップしません。

以下のサンプルコードでは、配列[1, 2, , 4]の欠落している要素はスキップされ、1 + 2 + 4 = 7が結果として出力されます。

一方、配列[1, 2, undefined, 4]undefinedはスキップされず、1 + 2 + undefined + 4となり、NaNが結果として出力されます。

console.log([1, 2, , 4].reduce((a, b) => a + b)); // 7
console.log([1, 2, undefined, 4].reduce((a, b) => a + b)); // NaN

本記事のまとめ

この記事では配列を操作するメソッド『reduceメソッド』について、以下の内容を説明しました。

  • reduceメソッドとは
  • reduceメソッドの構文
  • reduceメソッドの使い方
    • 配列の要素の合計を計算する
    • 配列の要素を結合する
    • 最大値・最小値を求める
    • オブジェクトの配列を一つのオブジェクトに変換する
    • ネストされた配列をフラットにする
  • reduceメソッドの特徴
    • 配列が空の場合にはエラーになる
    • 空の要素はスキップするが、値がundefinedの場合はスキップしない

お読み頂きありがとうございました。