【JavaScript】配列の最大値・最小値を取得する方法!reduceメソッドを使おう!

JavaScriptで『配列の最大値・最小値を取得する方法』について、以下の内容をサンプルコードを用いて分かりやすく説明するように心掛けています。ご参考になれば幸いです。

  • reduce()で配列の最大値・最小値を取得する方法
  • Math.max.apply()Math.min.apply()で配列の最大値・最小値を取得する方法
  • Math.max()Math.min()で配列の最大値・最小値を取得する方法
  • Math.max.apply()Math.min.apply()Math.max()Math.min()の注意点

reduce()で配列の最大値・最小値を取得する方法

reduceメソッドを使用すると、配列の最大値と最小値を取得することができます。

reduce()で配列の最大値を取得する方法

reduceメソッドを使用して、配列の最大値を取得するサンプルコードを以下に示します。

const arr = [10, 5, 20, 3, 7];
const max = arr.reduce((acc, cur) => Math.max(acc, cur), -Infinity);
console.log(max); // 20

reduce()で配列の最小値を取得する方法

reduceメソッドを使用して、配列の最小値を取得するサンプルコードを以下に示します。

const arr = [10, 5, 20, 3, 7];
const min = arr.reduce((acc, cur) => Math.min(acc, cur), Infinity);
console.log(min); // 3

後ほど、Math.max.apply()Math.min.apply()Math.max()Math.min()を使用して、配列の最大値と最小値を取得する方法も説明しますが、これらの方法は大規模な配列では誤った値を返す可能性があるため、推奨されません。

このような問題を避けるためにも、reduceメソッドを使用して配列の最大値と最小値を取得する方法を推奨します。

Math.max.apply()とMath.min.apply()で配列の最大値・最小値を取得する方法

Math.max.applyメソッドとMath.min.applyメソッドを使用しても、配列の最大値と最小値を取得することができます。

Math.max.apply()で配列の最大値を取得する方法

Math.max.applyメソッドを使用して、配列の最大値を取得するサンプルコードを以下に示します。

const arr = [10, 5, 20, 3, 7];
const max = Math.max.apply(null, arr);
console.log(max); // 20

Math.min.applyで配列の最小値を取得する方法

Math.min.applyメソッドを使用して、配列の最小値を取得するサンプルコードを以下に示します。

const arr = [10, 5, 20, 3, 7];
const min = Math.min.apply(null, arr);
console.log(min); // 3

Math.max.apply()Math.min.apply()を使用して配列の最大値・最小値を取得する方法は、大規模な配列では誤った値を返す可能性があるため、推奨されません(この件については、後ほど説明します)。

Math.max()とMath.min()で配列の最大値・最小値を取得する方法

Math.maxメソッドとMath.minメソッドは引数として複数の数値を与える必要があるため、配列を直接渡してしまうとNaNを返します。サンプルコードを以下に示します。

const arr = [10, 5, 20, 3, 7];

// 直接配列を渡すとNaNが返される例
const max_NaN = Math.max(arr);
const min_NaN = Math.min(arr);

console.log(max_NaN); // NaN
console.log(min_NaN); // NaN

// 数値を個別に渡すと正しい結果が返される例
const max = Math.max(10, 5, 20, 3, 7);
const min = Math.min(10, 5, 20, 3, 7);

console.log(max); // 20
console.log(min); // 3

上記のサンプルコードから分かるように、Math.maxメソッドとMath.minメソッドに配列を直接渡すとNaNが返されます。

しかし、スプレッド構文を使用すると、配列を展開してMath.maxメソッドやMath.minメソッドの引数として渡すことができるので、配列の最大値と最小値を取得することができます。

Math.max()の引数にスプレット構文を使用して、配列の最大値を取得する方法

Math.maxメソッドの引数にスプレット構文を使用して、配列の最大値を取得するサンプルコードを以下に示します。

const arr = [10, 5, 20, 3, 7];
const max = Math.max(...arr);
console.log(max); // 20

Math.min()の引数にスプレット構文を使用して、配列の最小値を取得する方法

Math.minメソッドの引数にスプレット構文を使用して、配列の最小値を取得するサンプルコードを以下に示します。

const arr = [10, 5, 20, 3, 7];
const min = Math.min(...arr);
console.log(min); // 3

Math.max()Math.min()を使用して配列の最大値・最小値を取得する方法は、大規模な配列では誤った値を返す可能性があるため、推奨されません(この件については、後ほど説明します)。

Math.max.apply()・Math.min.apply()・Math.max()・Math.min()の注意点

MDN web docs: Math.max()の公式ページには以下のことが記載されています。

しかし、要素の数が多い大規模な配列では、スプレッド構文 (...) と apply のどちらも、失敗するか誤った値を返す可能性があります。なぜなら、配列の要素を関数の引数として渡そうとしているからです。

MDN web docs: Math.max()

また、MDN web docs: Function.prototype.apply()には次のように記載されています。

しかし注意してください。この方法で apply を使う場合、JavaScript エンジンの引数の長さ上限を超えてしまう危険があります。
多すぎる (おおよそ数万個以上だと思って下さい) 引数を与えた結果は、その上限が特に決まっていない (本当に任意の巨大なデータのかたまりに対してさえ) ためエンジンによって (JavaScriptCore ライブラリでは引数の上限は65536であるとハードコーディングされています) 異なります。例外を投げるエンジンも存在します。
さらに酷い場合では、関数へ実際に渡す引数の数を勝手に制限するものもあります。

MDN web docs: Function.prototype.apply()

つまり、JavaScriptエンジンには引数の数に制限があるため、非常に大きな配列に対してMath.max.applyメソッドやMath.min.applyメソッド、あるいはスプレッド構文...を使う際に問題が生じる可能性があります。引数の数が上限を超えると、例外がスローされたり、誤った値が返されたりすることがあります。

例えば、配列の最大値(最小値)を求めようとしている際に、場合によっては配列の途中までの最大値(最小値)が返ってきてしまうことがあるということです。サンプルコードを以下に示します。

// 引数の数が3つまでと制限されている場合
let arr = [5, 2, 3, 1, 10];
let max = Math.max.apply(null, arr); // => 5
let min = Math.min.apply(null, arr); // => 2

console.log(max); // 本来は10だが、5を返す
console.log(min); // 本来は1だが、2を返す

上記の例では、本来最大値が10、最小値が1であるべきですが、Math.max.applyメソッドおよびMath.min.applyメソッドが配列を途中で切ってしまっているため、誤った値が返されています。このような問題を避けるためにも、reduceメソッドを使用して配列の最大値と最小値を取得する方法を推奨します。

本記事のまとめ

この記事ではJavaScriptで『配列の最大値・最小値を取得する方法』について、以下の内容を説明しました。

  • reduce()で配列の最大値・最小値を取得する方法
  • Math.max.apply()Math.min.apply()で配列の最大値・最小値を取得する方法
  • Math.max()Math.min()で配列の最大値・最小値を取得する方法
  • Math.max.apply()Math.min.apply()Math.max()Math.min()の注意点

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