Bagaimana saya bisa menemukan jumlah terbesar yang terkandung dalam array JavaScript?


206

Saya memiliki objek JavaScript Array sederhana yang berisi beberapa angka.

[267, 306, 108]

Apakah ada fungsi yang akan menemukan angka terbesar dalam array ini?


22
Math.max(...[267, 306, 108]);
Jacksonkr

Jawaban:


315

Resig untuk menyelamatkan:

Array.max = function( array ){
    return Math.max.apply( Math, array );
};

Peringatan : karena jumlah maksimum argumen serendah 65535 pada beberapa VM , gunakan for for loop jika Anda tidak yakin arraynya sekecil itu.


15
Ah, tapi sekarang ia memiliki SO Sticker of Quality yang ditempelkan dalam mode yang hanya sedikit bengkok!
Shog9

2
FWIW, jika kinerja merupakan faktor dalam solusi Anda, saya akan menguji itu dibandingkan dengan fungsi Anda yang mudah dikodekan untuk memastikan kinerjanya baik. Kami cenderung berasumsi bahwa implementasi asli akan lebih cepat; pada kenyataannya, biaya applypanggilan dapat mencuci dengan sangat mudah.
TJ Crowder

2
Bagaimana jika panjang array saya lebih besar dari batas jumlah parameter?
lukas.pukenis

3
@CrescentFresh menurut ini: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… itu di-hardcode ke 65535. Menurut ini: code.google.com/p/v8/issues/detail?id = 172 dan berdasarkan pengetahuan bahwa argumen didorong ke tumpukan, kami tahu bahwa itu tidak terbatas
lukas.pukenis

9
Juga, metode ini tidak kuat. Gagal jika array Anda lebih besar dari ukuran stack mamximum yang menghasilkanRangeError: Maximum call stack size exceeded.
Mark Lundin

197

Anda dapat menggunakan fungsi terapkan, untuk memanggil Math.max :

var array = [267, 306, 108];
var largest = Math.max.apply(Math, array); // 306

Bagaimana itu bekerja?

Fungsi terapkan digunakan untuk memanggil fungsi lain, dengan konteks dan argumen yang diberikan, disediakan sebagai array. Fungsi min dan maks dapat mengambil sejumlah argumen input yang berubah-ubah: Math.max (val1, val2, ..., valN)

Jadi, jika kita memanggil:

Math.min.apply(Math, [1,2,3,4]);

Fungsi yang berlaku akan menjalankan:

Math.min(1,2,3,4);

Perhatikan bahwa parameter pertama, konteksnya, tidak penting untuk fungsi-fungsi ini karena mereka statis, mereka akan bekerja terlepas dari apa yang dilewatkan sebagai konteks.


2
Whoa Anda memberikan jawaban Anda dengan banyak usaha: D
ShrekOverflow

1
Itu hebat. Tetapi bagaimana jika panjang array saya melebihi batas ukuran parameter (fungsi)? Lalu bagaimana ?
lukas.pukenis

1
Saya suka jawaban ini lebih baik daripada yang lain karena ini menjelaskan apa yang semuanya lakukan dan mengapa. +1
Marvin

59

Sintaks termudah, dengan operator spread baru :

var arr = [1, 2, 3];
var max = Math.max(...arr);

Sumber: Mozilla MDN


2
Namun, keduanya menyebar (...) dan menerapkan akan gagal atau mengembalikan hasil yang salah jika array memiliki terlalu banyak elemen developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Green

@Green FWIW, batas jumlah parameter adalah 65536 (setidaknya di Chrome) ([sumber ( bugs.webkit.org/show_bug.cgi?id=80797)] ). Jadi jika array Anda memiliki lebih dari 65536 elemen, jawaban ini tidak akan berfungsi.
mgthomas99

4
65536 seharusnya cukup untuk siapa pun
vsync

41

Saya bukan ahli JS, tetapi saya ingin melihat bagaimana metode ini menumpuk, jadi ini adalah praktik yang baik bagi saya. Saya tidak tahu apakah ini secara teknis cara yang tepat untuk menguji kinerja ini, tapi saya hanya menjalankannya satu per satu, seperti yang Anda lihat dalam kode saya.

Menyortir dan mendapatkan nilai 0 sejauh ini merupakan metode terburuk (dan itu mengubah urutan array Anda, yang mungkin tidak diinginkan). Bagi yang lain, perbedaannya dapat diabaikan kecuali Anda berbicara jutaan indeks.

Hasil rata-rata dari lima proses dengan array angka indeks 100.000 acak:

  • mengurangi mengambil 4.0392ms untuk dijalankan
  • Math.max.apply membutuhkan 3,3742ms untuk dijalankan
  • menyortir dan mendapatkan nilai 0 butuh 67,4724 ms untuk dijalankan
  • Math.max dalam pengurangan () membutuhkan 6.5804ms untuk dijalankan
  • fungsi findmax khusus membutuhkan 1,6102ms untuk dijalankan

var performance = window.performance

function findmax(array)
{
  var max = 0,
      a = array.length,
      counter

  for (counter=0;counter<a;counter++)
  {
      if (array[counter] > max)
      {
          max = array[counter]
      }
  }
  return max
}

function findBiggestNumber(num) {
  var counts = []
  var i
  for (i = 0; i < num; i++) {
    counts.push(Math.random())
  }

  var a, b

  a = performance.now()
  var biggest = counts.reduce(function(highest, count){
        return highest > count ? highest : count
      }, 0)
  b = performance.now()
  console.log('reduce took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest2 = Math.max.apply(Math, counts)
  b = performance.now()
  console.log('Math.max.apply took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest3 = counts.sort(function(a,b){return b-a;})[0]
  b = performance.now()
  console.log('sorting and getting the 0th value took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest4 = counts.reduce(function(highest, count){
        return Math.max(highest,count)
      }, 0)
  b = performance.now()
  console.log('Math.max within reduce() took ' + (b - a) + ' ms to run')

  a = performance.now()
  var biggest5 = findmax(counts)
  b = performance.now()
  console.log('custom findmax function took ' + (b - a) + ' ms to run')
  console.log(biggest + '-' + biggest2 + '-' + biggest3 + '-' + biggest4 + '-' + biggest5)

}

findBiggestNumber(1E5)

7
Bagi saya, ini adalah jawaban terbaik untuk pertanyaan ini.
rzelek

1
Saya telah membuat jsperf testsuntuk di atas
vsync

37

Saya telah menemukan bahwa untuk array yang lebih besar (~ elemen 100k), sebenarnya membayar untuk hanya mengulangi array dengan forloop sederhana , berkinerja ~ 30% lebih baik daripada Math.max.apply():

function mymax(a)
{
    var m = -Infinity, i = 0, n = a.length;

    for (; i != n; ++i) {
        if (a[i] > m) {
            m = a[i];
        }
    }

    return m;
}

Hasil benchmark


3
FWIW, keluar menjadi 84% sekarang di Chrome 31.
Ilan Biala

31

Anda bisa mengurutkan array dalam urutan menurun dan mendapatkan item pertama:

[267, 306, 108].sort(function(a,b){return b-a;})[0]

4
Saya menganggap Anda juga bisa menyortir dan mendapatkan item terakhir ...?
Shog9

@ Shog9: Ya, tetapi Anda harus menentukan fungsi perbandingan sendiri:sort(function(a,b){return b-a;})
Gumbo

9
Ah. Saya berpikir lebih seperti:[...].sort().pop()
Shog9

4
"menemukan nomor memerlukan urutan-n, pengurutan mengambil antara urutan (n log n) untuk memesan (n kuadrat), bergantung pada algoritma pengurutan yang digunakan" - webmasterworld.com/forum91/382.htm
Marco Luglio

2
Juga perlu diingat bahwa ini mengurutkan array, yang mungkin atau mungkin bukan efek samping yang diinginkan. Solusi yang berlaku adalah kinerja yang lebih baik dan tidak memiliki efek samping.
Caleb

28

Bagaimana dengan ini:

var arr = [1,2,3,4];

var largest = arr.reduce(function(x,y){
       return (x > y) ? x : y;
});

console.log(largest);

Seandainya saya melihat jawaban ini pertama (saat ini di bagian bawah daftar) saya akan menghemat dua jam.
user139301

1
Pendekatan Math.max mungkin yang paling standar, tapi saya mendapatkan stack overflow ketika array terlalu besar (500K). Jawaban ini cepat dan efisien dan yang akhirnya saya gunakan sendiri, jadi saya memilih yang ini.
Jay

8

bagaimana dengan menggunakan Array.reduce ?

[0,1,2,3,4].reduce(function(previousValue, currentValue){
  return Math.max(previousValue,currentValue);
});

Nilai awal harus diatur ke -Infinity.
Ja͢ck

@ Jack, mengapa ini dibutuhkan? bahkan dengan array semua angka negatif, saya mendapatkan hasil yang valid.
CodeToad

1
Ini adalah kasus tepi di mana array kosong.
Ja͢ck

5

Hampir semua jawaban menggunakan Math.max.apply()yang bagus dan keren tetapi memiliki keterbatasan.

Argumen fungsi ditempatkan pada tumpukan yang memiliki sisi negatif - batas. Jadi jika array Anda lebih besar dari batas itu akan gagalRangeError: Maximum call stack size exceeded.

Untuk menemukan ukuran tumpukan panggilan saya menggunakan kode ini:

var ar = [];
for (var i = 1; i < 100*99999; i++) {
  ar.push(1);
  try {
    var max = Math.max.apply(Math, ar);
  } catch(e) {
    console.log('Limit reached: '+i+' error is: '+e);
    break;
  }
}

Itu terbukti menjadi yang terbesar di FireFox di mesin saya - 591519 . Ini berarti bahwa jika array Anda berisi lebih dari 5.915.19 item, Math.max.apply()akan menghasilkan RangeError .

Solusi terbaik untuk masalah ini adalah cara berulang (kredit: https://developer.mozilla.org/ ):

max = -Infinity, min = +Infinity;

for (var i = 0; i < numbers.length; i++) {
  if (numbers[i] > max)
    max = numbers[i];
  if (numbers[i] < min)
    min = numbers[i];
}

Saya telah menulis tentang pertanyaan ini di blog saya di sini .


1
Ini tidak adil. Saya ingin jawabannya di sini, di SO, bukan tautan lain ke sumber pihak ketiga lainnya. Terutama ketika itu dikombinasikan dengan "semuanya di sini buruk, tapi pergi, lihat, itu sangat bagus di blog saya ..."
osa

@SergeyOrshanskiy tautan ke pihak ketiga berfungsi sangat baik jika diperbarui dengan solusi dan solusi baru. Juga tidak perlu merasa tersinggung. Orang-orang hanya ingin menyelesaikan masalah Anda juga. Saya ingin menyelesaikannya juga, jadi saya menulisnya di blog saya
lukas.pukenis


5

Menemukan nilai maks dan minimum dengan cara mudah dan manual. Kode ini jauh lebih cepat daripada Math.max.apply; Saya telah mencoba hingga 1000 ribu angka dalam array.

function findmax(array)
{
    var max = 0;
    var a = array.length;
    for (counter=0;counter<a;counter++)
    {
        if (array[counter] > max)
        {
            max = array[counter];
        }
    }
    return max;
}

function findmin(array)
{
    var min = array[0];
    var a = array.length;
    for (counter=0;counter<a;counter++)
    {
        if (array[counter] < min)
        {
            min = array[counter];
        }
    }
    return min;
}

findmax()memberikan hasil yang salah jika hanya ada angka negatif dalam array; findmin()memberikan hasil yang salah untuk array kosong.
Ja͢ck


3

Ya tentu saja ada: Math.max.apply(null,[23,45,67,-45]) dan hasilnya kembali 67;



1

Jangan lupa bahwa membungkus dapat dilakukan dengan Function.prototype.bind, memberikan Anda "semua-asli" fungsi .

var aMax = Math.max.apply.bind(Math.max, Math);
aMax([1, 2, 3, 4, 5]); // 5

1

Anda juga dapat memperluas Arrayuntuk memiliki fungsi ini dan menjadikannya bagian dari setiap array.

Array.prototype.max = function(){return Math.max.apply( Math, this )};
myArray = [1,2,3];

console.log( myArray.max() );

1
Sangat tidak efisien.
Frank Schmitt

@ FrankSchmitt, terima kasih, saya setuju. Jawaban asli bukanlah solusi yang baik. Urutkan secara default tidak mengurutkan angka, itu memperlakukan elemen sebagai string. Mengedit jawaban saya untuk jenis yang tepat.
Izz

Itu bukan poin saya. Menyortir Array untuk menemukan maksimum per se sangat tidak efisien, karena dibutuhkan setidaknya operasi N log N, sedangkan menemukan maksimum dapat dilakukan dalam operasi N.
Frank Schmitt

1

Anda juga dapat menggunakan forEach :

var maximum = Number.MIN_SAFE_INTEGER;

var array = [-3, -2, 217, 9, -8, 46];
array.forEach(function(value){
  if(value > maximum) {
    maximum = value;
  }
});

console.log(maximum); // 217


1

Menggunakan - Array.prototype.reduce()keren!

[267, 306, 108].reduce((acc,val)=> (acc>val)?acc:val)

di mana acc = akumulator dan val = nilai saat ini ;

var a = [267, 306, 108].reduce((acc,val)=> (acc>val)?acc:val);

console.log(a);


1

Anda dapat mencoba ini,

var arr = [267,306,108];
var largestNum = 0;
for(i=0;i<arr.length;i++) {
   if(arr[i]>largest){
    var largest = arr[i];
   }
}
console.log(largest);

1

Saya baru saja mulai dengan JS tetapi saya pikir metode ini akan bagus:

var array = [34, 23, 57, 983, 198];<br>
var score = 0;

for(var i = 0; i = array.length; i++) {
  if(array[ i ] > score) {
    score = array[i];
  }
}

Ini akan bermasalah jika arrayhanya berisi angka negatif.
Teepeemm

0

Temukan angka terbesar dalam array multidimensi

var max = []; 

for(var i=0; arr.length>i; i++ ){

   var arra = arr[i];
   var largest = Math.max.apply(Math, arra);
   max.push(largest);

   }
return max;

Itu selalu disarankan untuk menambahkan beberapa penjelasan rumit ke kode Anda, terutama jika sudah ada beberapa jawaban lain. Mengapa ini berbeda / lebih baik?
Bowdzone

@Bowdzone, terima kasih atas komentarnya. cara ini sangat mendasar yang membuatnya mudah dipahami dengan sedikit pengetahuan hanya beberapa metode.
Liveindream

Ini tidak mengembalikan angka terbesar, itu mengembalikan array dari jumlah terbesar dari setiap array dalam array multidimensi. Anda perlu menambahkan mis var tmax = Math.max.apply(Math, max), atau lebih baik lagi, menggunakan penutupan fungsi loop misalnya di stackoverflow.com/a/54980012/7438857 . Dengan modifikasi ini, lebih baik dijawab pertanyaan terpisah, bagaimana Anda "menemukan angka terbesar dalam array multidimensi", atau di stackoverflow.com/questions/32616910/… . WIP: jsfiddle.net/jamesray/3cLu9for/8 .
James Ray

stackoverflow.com/a/32617019/7438857 adalah jawaban yang lebih baik untuk pertanyaan yang tepat, sementara jawaban ini tidak menjawab pertanyaan di atas, ia mengembalikan jumlah terbesar di setiap array dalam array multidimensi.
James Ray

0

Jalankan ini:

Array.prototype.max = function(){
    return Math.max.apply( Math, this );
};

Dan sekarang coba [3,10,2].max()kembali10


0

Temukan nilai Max dan Min menggunakan Bubble Sort

    var arr = [267, 306, 108];

    for(i=0, k=0; i<arr.length; i++) {
      for(j=0; j<i; j++) {
        if(arr[i]>arr[j]) {
          k = arr[i];
          arr[i] = arr[j];
          arr[j] = k;
        }
      }
    }
    console.log('largest Number: '+ arr[0]);
    console.log('Smallest Number: '+ arr[arr.length-1]);


1
(1) Array Javascript sudah memiliki fungsi sortir O (n log n). (2) Bubble sort adalah O (n ^ 2). (3) Menemukan min dan maks adalah O (n).
Teepeemm

0

Coba ini

function largestNum(arr) {
  var currentLongest = arr[0]

  for (var i=0; i< arr.length; i++){
    if (arr[i] > currentLongest){
      currentLongest = arr[i]
    }
  }

  return currentLongest
}

1
Apakah jawaban ini jauh berbeda dari yang lain di halaman ini?
Teepeemm

0

Sesuai komentar @ Quasimondo , yang tampaknya sebagian besar telah dilewatkan, di bawah ini tampaknya memiliki kinerja terbaik seperti yang ditunjukkan di sini: https://jsperf.com/finding-maximum-element-in-an-array . Perhatikan bahwa sementara untuk array dalam pertanyaan, kinerja mungkin tidak memiliki efek yang signifikan, untuk kinerja array besar menjadi lebih penting, dan sekali lagi seperti yang dicatat menggunakan Math.max()bahkan tidak berfungsi jika panjang array lebih dari 65.535. Lihat juga jawaban ini .

function largestNum(arr) {
    var d = data;
    var m = d[d.length - 1];
    for (var i = d.length - 1; --i > -1;) {
      if (d[i] > m) m = d[i];
    }
    return m;
}

0

Pendekatan rekursif tentang cara melakukannya menggunakan operator ternary

const findMax = (arr, max, i) => arr.length === i ? max :
  findMax(arr, arr[i] > max ? arr[i] : max, ++i)

const arr = [5, 34, 2, 1, 6, 7, 9, 3];
const max = findMax(arr, arr[0], 0)
console.log(max);


0

Satu for/ofsolusi loop:

const numbers = [2, 4, 6, 8, 80, 56, 10];


const findMax = (...numbers) => {
  let currentMax = numbers[0]; // 2

  for (const number of numbers) {
    if (number > currentMax) {
      console.log(number, currentMax);
      currentMax = number;
    }
  }
  console.log('Largest ', currentMax);
  return currentMax;
};

findMax(...numbers);

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.