配列内の最大値のインデックスを返します


139

私はこれを持っています:

var arr = [0, 21, 22, 7];

最も高い値のインデックスを別の変数に返す最良の方法は何ですか?


21
それは重複ではありません。質問を読んでください... @Dancrumb SOが機能する方法は、私がこの質問を投稿することです。何十年もの間、人々はそれを見つけ、読んで、貢献者が下に投稿した情報に感謝します!
スティーブン、

1
@Stephenは逆に、このFAQを読むと、主観的な質問(「何が最善の方法か...」で始まる質問など)が明示的に推奨されていないことがわかります。ただし、SOはコミュニティなので、コミュニティがこの質問をクローズするかどうかを決定する必要があります。
Dancrumb、2012

6
配列内の最大数を見つけることは、配列内の最大数のインデックスを見つけることと同じではありません。したがって、この質問は重複として投稿されたその参照の重複ではありません。
Fzs2 2013

15
これは重複ではありません-または少なくとも参照されている質問ではありません。私はこれについての反対票を理解することができません-何かをする最善の方法をSOに尋ねることはできないと言うのは馬鹿げているし、そのような簡潔な質問にはコード例は必要ありません。参照されている「重複」の投票数が+30で、非常によく似たスタイルで尋ねられたこの並行BUT DIFFERENT質問の票数が-3であるのはどうしてですか。質問をもう一度読んで、重複としてマークされている投票を削除してください。「のインデックス」は、質問のタイトルで見つける必要があるキーフレーズです。
2013年

@Dancrumb stackoverflow.com/help/dont-askの現在のアドバイスでは、すべての回答が等しく有効である場合にのみ、主観的な質問を避けています。この場合、「最高」は、パフォーマンス、簡潔さ、表現力の点で明確に評価できます。
user234461

回答:


165

信頼性が高く、古いブラウザで動作するため、これがおそらく最良の方法です。

function indexOfMax(arr) {
    if (arr.length === 0) {
        return -1;
    }

    var max = arr[0];
    var maxIndex = 0;

    for (var i = 1; i < arr.length; i++) {
        if (arr[i] > max) {
            maxIndex = i;
            max = arr[i];
        }
    }

    return maxIndex;
}

このワンライナーもあります:

let i = arr.indexOf(Math.max(...arr));

RangeErrorただし、必要な比較の2倍の比較を実行し、大規模な配列ではをスローします。機能にこだわる。


1
この関数は、最大の値に対して最初に見つかったインデックスを返します。同じ最高値を持つ複数のインデックスがあるとしましょう。これらのインデックスをすべて取得するにはどうすればよいですか?
ed1nh0

1
@ ed1nh0:複数のパスを作成するのが簡単な方法です。で最大値を見つけ、最大値const max = arr.reduce((m, n) => Math.max(m, n))のインデックスは[...arr.keys()].filter(i => arr[i] === max)です。
Ry-

[...arr.keys()]エラーを出力します:unexpected token
ed1nh0

@ ed1nh0:どのブラウザ/環境をターゲットにしていますか?
Ry-

クロム。私はVueJSを使用していますが、問題はwebpack構成にあると思います。
ed1nh0

82

一行で、おそらくより速くarr.indexOf(Math.max.apply(Math, arr))

var a = [0, 21, 22, 7];
var indexOfMaxValue = a.reduce((iMax, x, i, arr) => x > arr[iMax] ? i : iMax, 0);

document.write("indexOfMaxValue = " + indexOfMaxValue); // prints "indexOfMaxValue = 2"

どこ:

  • iMax-最良の指標これまでのところ(最初の繰り返しで、これまでの最大要素のインデックス、iMax = 02番目の引数があるためreduce()0、我々は二番目の引数を省略することはできませんreduce()私たちの場合)
  • x -現在テストされている配列の要素
  • i -現在テストされているインデックス
  • arr-私たちの配列([0, 21, 22, 7]

reduce()メソッドについて( "JavaScript:The Definitive Guide" by David Flanagan):

reduce()は2つの引数を取ります。1つは、リダクション演算を実行する関数です。この削減関数のタスクは、2つの値を何らかの方法で結合または削減して単一の値にし、その削減された値を返すことです。

reduce()で使用される関数は、forEach()およびmap()で使用される関数とは異なります。使い慣れた値、インデックス、配列の値は、2番目、3番目、4番目の引数として渡されます。最初の引数は、これまでの削減の累積結果です。関数の最初の呼び出しでは、この最初の引数は、reduce()の2番目の引数として渡した初期値です。以降の呼び出しでは、関数の前回の呼び出しで返された値です。

初期値なしでreduce()を呼び出すと、配列の最初の要素が初期値として使用されます。つまり、リダクション関数の最初の呼び出しでは、1番目と2番目の引数として1番目と2番目の配列要素が使用されます。


12
@traxiumあなたの説明は素晴らしいですが、より記述的な変数を使用すれば、関数型プログラミングが苦手な人にとっても例がより明確になる可能性があります。言う:arr.reduce((bestIndexSoFar, currentlyTestedValue, currentlyTestedIndex, array) => currentlyTestedValue > array[bestIndexSoFar] ? currentlyTestedIndex : bestIndexSoFar, 0);、として記述することができる:反復配列は、インデックス0(第2パラメータ)から出発した場合、currentlyTestedValueはの要素の値よりも大きいbestIndexSoFar、戻りcurrentlyTestedIndexをとして次の反復にbestIndexSoFar
niieani

1
@traxium素晴らしい答え。@niieaniにも同意します。ここに私が実装した実際の例を示しますthis.methods.reduce((methodIndex, currentMethod, currentMethodIndex, methods) => currentMethod.price <= methods[methodIndex].price ? currentMethodIndex : methodIndex, 0)
ダニエル

2
@DanielK、「完全な」パラメータ名の答えは、1つのスタックオーバーフロー行に収まりません。水平スクロールバーが表示され、水平スクロール中にスニペットを読むのはあまり便利ではありません。とにかく提案をありがとう。別の方法で回答を編集しました。
traxium

FPソリューションの場合は@traxium +1。JSを使い始めたばかりの人にとっては病的に複雑ですが、このソリューションは、OPの問題を解決するための最も高性能なソリューションの1つでもあります。
SeaWarrior404

jsben.ch/ujXlkによると、他の方法の方が高速です。
VFDan

47

ここに別のソリューションがあります。spreadオペレーターを使用してES6を使用している場合:

var arr = [0, 21, 22, 7];

const indexOfMaxValue = arr.indexOf(Math.max(...arr));

6

誤解しない限り、自分で関数を書くことだと思います。

function findIndexOfGreatest(array) {
  var greatest;
  var indexOfGreatest;
  for (var i = 0; i < array.length; i++) {
    if (!greatest || array[i] > greatest) {
      greatest = array[i];
      indexOfGreatest = i;
    }
  }
  return indexOfGreatest;
}

6

アンダースコアを使用している場合は、この素敵な短いワンライナーを使用できます。

_.indexOf(arr, _.max(arr))

最初に、配列内の最大の項目(この場合は22)の値を見つけます。次に、配列内の22(この場合は2)のインデックスを返します。


6

maxを使用する別のソリューションreduce

[1,2,5,0,4].reduce((a,b,i) => a[0] < b ? [b,i] : a, [Number.MIN_VALUE,-1])
//[5,2]

これは[5e-324, -1]、配列が空の場合に返されます。インデックスだけが必要な場合は、[1]後に付けます。

経由の最小値(>およびに変更MAX_VALUE):

[1,2,5,0,4].reduce((a,b,i) => a[0] > b ? [b,i] : a, [Number.MAX_VALUE,-1])
//[0, 3]

1

編集:数年前、私はこれに対する答えを与えましたが、それは全体的で、具体的すぎ、複雑すぎました。だから私はそれを編集しています。上記の機能的な答えは、読みやすさではなく、きちんとした要素に適しています。しかし、私がjavascriptに慣れていれば、それも好きになるでしょう。

疑似コード:

最大値を含むインデックスを追跡します。最初はインデックス0が最大であると仮定します。現在のインデックスと比較してください。必要に応じて、インデックスを最大値で更新します。

コード:

var mountains = [3, 1, 5, 9, 4];

function largestIndex(array){
  var counter = 1;
  var max = 0;

  for(counter; counter < array.length; counter++){
    if(array[max] < array[counter]){
        max = counter;
    }
  }
  return max;
}

console.log("index with largest value is: " +largestIndex(mountains));
// index with largest value is: 3

ありがとう!私はそれをさらにいじる必要がありました。
ロススタッドマン2018

1
function findIndicesOf(haystack, needle)
{
    var indices = [];

    var j = 0;
    for (var i = 0; i < haystack.length; ++i) {
        if (haystack[i] == needle)
            indices[j++] = i;
    }
    return indices;
}

合格arrayhaystackMath.max(...array)しますneedle。これにより、配列のすべての最大要素が得られ、より拡張可能になります(たとえば、最小値も見つける必要があります)。


1

配列のコピーを作成して降順に並べ替えると、コピーの最初の要素が最大になります。元の配列でそのインデックスを見つけることができます。

var sorted = [...arr].sort((a,b) => b - a)
arr.indexOf(sorted[0])

時間の複雑さは、コピーの場合はO(n)、並べ替えの場合はO(n * log(n))、indexOfの場合はO(n)です。

より速く実行する必要がある場合、Ryの答えはO(n)です。


0

 var arr=[0,6,7,7,7];
 var largest=[0];
 //find the largest num;
 for(var i=0;i<arr.length;i++){
   var comp=(arr[i]-largest[0])>0;
      if(comp){
	  largest =[];
	  largest.push(arr[i]);
	  }
 }
 alert(largest )//7
 
 //find the index of 'arr'
 var arrIndex=[];
 for(var i=0;i<arr.length;i++){
    var comp=arr[i]-largest[0]==0;
	if(comp){
	arrIndex.push(i);
	}
 }
 alert(arrIndex);//[2,3,4]


-1

この関数の安定版は次のようになります。

// not defined for empty array
function max_index(elements) {
    var i = 1;
    var mi = 0;
    while (i < elements.length) {
        if (!(elements[i] < elements[mi]))
            mi = i;
        i += 1;
    }
    return mi;
}

この文脈で「安定」とはどういう意味ですか?
Ry-

彼が「適切」を意味していたと思います
Ikbel '18

-5

シンプルな

maxarr: function(){
let maxval = 0;
let maxindex = null;
for (i = 0; i < arr.length; i++){
if (arr[i] > maxval) {
maxval = arr[i];
maxindex = i;
}
}
}

申し訳ありませんが、投稿をはっきりと読んでいませんでした。コードを更新します
vidhyesh

回答をもう少し詳しく説明し(反対票を削除するのに役立ちます)、他の回答と区別してみてください(例:使用するリソースが少ない、または計算が速いなど)。(低品質の回答レビューの終了)。
ZF007

これは最大値のインデックスを返しません。これは最大値を返すだけです。
・クール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.