JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

【JavaScript】配列内の最小値が複数あるとき、そのすべてのインデックスを取得する方法

次のような数値の配列があるとします。

const arr = [1,2,3,4,1,7,8,9,1];

この配列から最小値(上の例では「1」)のインデックスを1つだけ取得したいのであれば、Math.minindexOf を組み合わせるだけで簡単に実現できます。

const min = Math.min.apply(Math, arr);
const ind = arr.indexOf(min);

このコードを実行すると、ind には 0 が代入されます。確かに正しい結果です。

しかし、配列内に最小値が複数存在する場合はどうでしょうか。上記の配列には「1」が3つ含まれています。このようなケースでは、最小値のインデックスをすべて格納した配列を返すのが望ましいでしょう。

つまり、この配列に対して期待する出力は次のとおりです。最小値「1」はインデックス 0、4、8 の3か所に存在します。

const ind = [0, 4, 8]

そこで本記事では、数値の配列を受け取り、その配列内に含まれる最小値のすべてのインデックスを配列として返すJavaScript 関数を作成していきます。

実装例

以下が実際のコードです。

const arr = [1,2,3,4,1,7,8,9,1];
const minArray = arr => {
    const min = arr.reduce((acc, val) => Math.min(acc, val), Infinity);
    const res = [];
    for(let i = 0; i < arr.length; i++){
        if(arr[i] !== min){
            continue;
        };
        res.push(i);
    };
    return res;
};
console.log(minArray(arr));

出力

コンソールには次のように表示されます。

[ 0, 4, 8 ]

コードの解説

① 最小値の算出

reduce メソッドを使い、初期値 Infinity と各要素を順番に Math.min で比較することで、配列全体の最小値を求めています。

const min = arr.reduce((acc, val) => Math.min(acc, val), Infinity);

Math.min.apply(...) やスプレッド構文(Math.min(...arr))でも最小値は取得できますが、要素数が非常に多い配列では引数展開によるエラー(スタックオーバーフロー)が発生する可能性があります。reduce を使う方法であれば、大きな配列でも安全に処理できる点がメリットです。

② 該当インデックスの収集

続く for 文で配列を先頭から走査し、要素が最小値と一致した場合のみ、その位置(インデックス)を結果配列 res に追加しています。

これにより、最小値が何個あっても、そのすべての出現位置を漏れなく取得できるようになります。

  1. JavaScriptのArray.prototype.find()メソッドとは?使い方をサンプルコードで解説

    Array.prototype.find() メソッドは、配列の中から指定した条件(テスト関数)を満たす最初の要素の値を返します。 条件に一致する要素が見つかった時点で検索を終了するため、大きな配列でも効率的に動作します。また、どの要素も条件を満たさなかった場合は undefined を返すという点も重要な特徴です。 find()メソッドの基本構文 arr.find(callback(element[, index[, array]])[, thisArg]) callback:各要素に対して実行されるテスト関数。true を返した要素が結果となります。 thisArg(省略可):callb

  2. 複数の値でJavaScript配列の要素を検索する方法

    JavaScriptである配列(arr)が、別の配列(arr1)の複数の値・すべての要素を含んでいるかどうかを確認したい場面はよくあります。そんなときは、every()メソッドとincludes()メソッドを組み合わせることで、シンプルに判定できます。以下はそのサンプルコードです。 コード例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content=