Mengembalikan indeks nilai terbesar dalam array

139

Aku punya ini:

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

Apa cara terbaik untuk mengembalikan indeks dari nilai tertinggi ke variabel lain?

Stephen
sumber
21
Itu bukan duplikat, baca pertanyaannya ... @ Dancrumb Cara SO bekerja adalah saya memposting pertanyaan ini dan selama beberapa dekade mendatang orang akan menemukannya, membacanya, dan berterima kasih atas informasi yang diposting oleh kontributor di bawah ini!
Stephen
1
@Stephen, sebaliknya, jika Anda membaca FAQ ini , Anda akan melihat bahwa pertanyaan subyektif (seperti yang dimulai dengan "Apa cara terbaik ...") tidak disarankan. Namun, SO adalah komunitas, jadi komunitaslah yang menentukan apakah pertanyaan ini harus ditutup atau tidak.
Dancrumb
6
Menemukan nomor terbesar dalam array tidak sama dengan menemukan indeks jumlah terbesar dalam array. Karenanya pertanyaan ini bukan duplikat dari referensi yang diposting sebagai duplikat.
Fzs2
15
Ini BUKAN duplikat - atau setidaknya bukan dari pertanyaan yang dirujuk. Saya tidak dapat memahami downvotes tentang ini - mengatakan Anda tidak bisa bertanya pada SO cara terbaik untuk melakukan sesuatu adalah menggelikan, dan tidak ada contoh kode yang diperlukan untuk pertanyaan singkat seperti itu. Bagaimana mungkin 'duplikat' yang dirujuk memiliki +30 suara, dan pertanyaan TETAPI BERBEDA paralel ini, ditanyakan dengan gaya yang sangat mirip, memiliki -3 suara? Harap baca kembali pertanyaan dan hapus suara Anda yang ditandai sebagai duplikat. "Indeks" adalah frasa kunci yang perlu Anda temukan dalam judul pertanyaan.
panekuk
@ Dancrumb Saran saat ini di stackoverflow.com/help/dont-ask mengecilkan pertanyaan subyektif hanya jika setiap jawaban sama-sama valid. Dalam hal ini, "terbaik" jelas dapat dievaluasi dalam hal kinerja, kesederhanaan dan ekspresif.
user234461

Jawaban:

165

Ini mungkin cara terbaik, karena dapat diandalkan dan berfungsi di browser lama:

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;
}

Ada juga satu kalimat ini:

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

Itu melakukan perbandingan dua kali lebih banyak yang diperlukan dan akan melemparkan RangeErrorpada array yang besar, meskipun. Saya akan tetap berpegang pada fungsinya.

Ry-
sumber
1
Ok fungsi ini mengembalikan indeks yang ditemui pertama untuk nilai terbesar. Katakanlah saya memiliki lebih dari satu indeks dengan nilai tertinggi yang sama, bagaimana cara mendapatkan semua indeks ini?
ed1nh0
1
@ ed1nh0: Cara mudah adalah membuat beberapa lintasan. Temukan max dengan const max = arr.reduce((m, n) => Math.max(m, n)), maka indeks max adalah [...arr.keys()].filter(i => arr[i] === max).
Ry-
[...arr.keys()]menghasilkan kesalahan:unexpected token
ed1nh0
@ ed1nh0: Browser / lingkungan manakah yang Anda targetkan?
Ry-
Chrome. Saya menggunakan VueJS dan saya kira masalahnya ada pada konfigurasi webpack.
ed1nh0
82

Dalam satu baris dan mungkin lebih cepat, maka 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"

Dimana:

  • iMax- indeks terbaik sejauh ini (indeks elemen maks sejauh ini, pada iterasi pertama iMax = 0karena argumen kedua reduce()adalah 0, kita tidak dapat menghilangkan argumen kedua reduce()dalam kasus kami)
  • x - elemen yang saat ini diuji dari array
  • i - indeks yang saat ini diuji
  • arr- array kami ( [0, 21, 22, 7])

Tentang reduce()metode (dari "JavaScript: The Definitive Guide" oleh David Flanagan):

mengurangi () membutuhkan dua argumen. Yang pertama adalah fungsi yang melakukan operasi pengurangan. Tugas fungsi reduksi ini adalah entah bagaimana menggabungkan atau mengurangi dua nilai menjadi nilai tunggal, dan mengembalikan nilai yang dikurangi tersebut.

Fungsi yang digunakan dengan mengurangi () berbeda dari fungsi yang digunakan dengan forEach () dan peta (). Nilai akrab, indeks, dan nilai array dilewatkan sebagai argumen kedua, ketiga, dan keempat. Argumen pertama adalah akumulasi hasil pengurangan sejauh ini. Pada panggilan pertama ke fungsi, argumen pertama ini adalah nilai awal yang Anda berikan sebagai argumen kedua untuk mengurangi (). Pada panggilan berikutnya, itu adalah nilai yang dikembalikan oleh pemanggilan fungsi sebelumnya.

Saat Anda memanggil pengurangan () tanpa nilai awal, ia menggunakan elemen pertama array sebagai nilai awal. Ini berarti bahwa panggilan pertama ke fungsi reduksi akan memiliki elemen array pertama dan kedua sebagai argumen pertama dan kedua.

traxium
sumber
12
@ Traxium Sementara penjelasan Anda bagus, contohnya bisa lebih jelas bagi mereka yang kurang ke pemrograman fungsional jika kami menggunakan variabel yang lebih deskriptif. Katakanlah: arr.reduce((bestIndexSoFar, currentlyTestedValue, currentlyTestedIndex, array) => currentlyTestedValue > array[bestIndexSoFar] ? currentlyTestedIndex : bestIndexSoFar, 0);, yang dapat digambarkan sebagai: iterate array dimulai dari indeks 0 (2 parameter), jika currentlyTestedValue lebih tinggi dari nilai elemen di bestIndexSoFar , kemudian kembali currentlyTestedIndex untuk iterasi berikutnya sebagai bestIndexSoFar .
niieani
1
@ Traxium Jawaban yang luar biasa. Saya juga setuju dengan @niieani Berikut ini adalah contoh dunia nyata saya dilaksanakan: this.methods.reduce((methodIndex, currentMethod, currentMethodIndex, methods) => currentMethod.price <= methods[methodIndex].price ? currentMethodIndex : methodIndex, 0).
Daniel
2
@DanielK, Jawaban dengan nama parameter "penuh" tidak akan cocok dalam satu baris stackoverflow. Akan muncul bilah gulir horizontal dan tidak nyaman untuk membaca cuplikan sambil menggulir secara horizontal. Pokoknya terima kasih atas sarannya. Saya mengedit jawabannya dengan cara lain.
Traxium
@traxium +1 untuk solusi FP. Sementara itu sangat rumit untuk seseorang yang baru memulai dengan JS, solusi Anda juga merupakan salah satu yang paling berkinerja untuk memecahkan masalah OP.
SeaWarrior404
Menurut jsben.ch/ujXlk , metode lain lebih cepat.
VFDan
47

Berikut adalah solusi lain, Jika Anda menggunakan ES6 menggunakan operator spread:

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

const indexOfMaxValue = arr.indexOf(Math.max(...arr));
Lanil Marasinghe
sumber
6

Kecuali saya salah, saya akan mengatakan itu untuk menulis fungsi Anda sendiri.

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;
}
Dan Tao
sumber
6

Jika Anda menggunakan garis bawah, Anda dapat menggunakan kalimat singkat berikut:

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

Pertama-tama akan menemukan nilai item terbesar dalam array, dalam hal ini 22. Kemudian akan mengembalikan indeks di mana 22 berada dalam array, dalam hal ini 2.

Kevin
sumber
6

Solusi lain menggunakan max reduce:

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

Ini mengembalikan [5e-324, -1]jika array kosong. Jika Anda ingin hanya indeks, taruh [1]setelah.

Min via (Ubah ke >dan MAX_VALUE):

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

EDIT: Bertahun-tahun yang lalu saya memberikan jawaban untuk ini yang kotor, terlalu spesifik, dan terlalu rumit. Jadi saya mengeditnya. Saya menyukai jawaban fungsional di atas untuk faktor rapi tetapi tidak mudah dibaca; tetapi jika saya lebih terbiasa dengan javascript maka saya mungkin akan menyukainya juga.

Kode palsu:

Lacak indeks yang berisi nilai terbesar. Asumsikan indeks 0 adalah yang terbesar pada awalnya. Bandingkan dengan indeks saat ini. Perbarui indeks dengan nilai terbesar jika perlu.

Kode:

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
ross studtman
sumber
Terima kasih! Saya harus mengacaukannya lebih lanjut.
ross studtman
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;
}

lolos arraydari haystackdan Math.max(...array)ke needle. Ini akan memberikan semua elemen max dari array, dan itu lebih dapat diperluas (misalnya, Anda juga perlu menemukan nilai min)

Edward Karak
sumber
1

Jika Anda membuat salinan array dan mengurutkannya, elemen pertama dari salinan akan menjadi yang terbesar. Daripada Anda dapat menemukan indeks dalam array asli.

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

Kompleksitas waktu adalah O (n) untuk salinan, O (n * log (n)) untuk penyortiran dan O (n) untuk indexOf.

Jika Anda perlu melakukannya lebih cepat, jawaban Ry adalah O (n).

rodurico
sumber
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]

mos wen
sumber
-1

Versi stabil dari fungsi ini terlihat seperti ini:

// 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;
}
Peter Stuifzand
sumber
Apa artinya "stabil" dalam konteks ini?
Ry-
Saya kira maksudnya "cocok"
Ikbel
-5

Sederhana

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
sumber
Maaf saya tidak membaca posting dengan jelas sekarang saya akan memperbarui kode
vidhyesh
tolong jelaskan jawaban Anda sedikit lebih jauh (membantu untuk menghapus downvotes) dan juga mencoba untuk membedakannya dari jawaban lain (yaitu: menggunakan lebih sedikit sumber daya atau lebih cepat dalam perhitungan ... dll). (Akhir Review Jawaban Berkualitas Rendah).
ZF007
Ini tidak mengembalikan indeks nilai maksimal; ini hanya mengembalikan nilai positif maks .
Cœur