概要
JavaScriptを用いて配列内の最大値、または最小値のインデックスを取得したい。
JavaScriptには標準で渡した引数の中で一番大きい値を返す Math.max はあるが、配列の中で一番大きい値は何番目かを知る機能はないため、今回は自分で作成してみる。
indexOfとMath.max(Math.min)を組み合わせる
- Math.max(min)メソッドは引数に渡した値のうち最大(最小)の値を返す。
- indexOfメソッドは引数に渡された値に一致する要素のインデックスを返す。
- この二つを組み合わせることで配列から最大(最小)の要素のインデックスを取得することができる。
注意点として、Math.max(Math.min)の引数に配列をとることができないため、スプレッド構文を使って展開する必要がある。
なお、このやり方には一つ問題点があるため記事の最後まで読んでいただきたい。
// 適当な数値の配列
const numArray = [ 3, 5, 13, 8, 25, 4 ];
// 最大値のインデックスを取得
const maxIndex = numArray.indexOf(Math.max(...numArray));
console.log(maxIndex) // => 4
// 最小値のインデックスを取得
const minIndex = numArray.indexOf(Math.min(...numArray));
console.log(minIndex) // => 0
無事、配列の中の最大要素(=25)のインデックス(=4)と、最小値(=3)のインデックス(=0)を取得することができました。
なお、最大の数値が複数ある場合は一番最初の index が取得できる
他にもfor文を使って原始的にインデックスを取得する方法もあるが、今回のやり方の方がわかりやすいと感じた。
しかし、この方法には問題が...
それはMath.maxで最大値を取得する際に使用できる配列の大きさには制限があるようで、それを超えてしまう場合は使うことができないようなのである。(最小値も同様)
しかし、要素の数が多い大規模な配列では、スプレッド構文 (...) と apply のどちらも、失敗するか誤った値を返す可能性があります。なぜなら、配列の要素を関数の引数として渡そうとしているからです。詳しくは apply をビルトイン関数と共に利用するを参照してください。 reduce の方法はこの問題が発生しません。
とのこと。そのため、簡単な配列ならこの方法でいいが、配列が大きい場合は下の方法を利用する。
indexOfとreduce()を組み合わせて要素のインデックスを取得する
reduce()を用いて配列の頭から二つずつ比較して最大値(最小値)を更新していく
const aryMax = function (a, b) {return Math.max(a, b);}
const aryMin = function (a, b) {return Math.min(a, b);}
// 適当な数値の配列
const numArray = [ 3, 5, 13, 8, 25, 4 ];
// 最大値と最小値を取得
const max = numArray.reduce(aryMax); // => 25
const min = numArray.reduce(aryMin); // => 3
// 最大値のインデックスを取得
const maxIndex = numArray.indexOf(max);
console.log(maxIndex) // => 4
// 最小値のインデックスを取得
const minIndex = numArray.indexOf(min);
console.log(minIndex) // => 0
これで大規模な配列が用意されていても安全。