Bir JavaScript dizisinde bulunan en büyük sayıyı nasıl bulabilirim?


206

Birkaç sayı içeren basit bir JavaScript dizi nesnesi var.

[267, 306, 108]

Bu dizideki en büyük sayıyı bulabilecek bir işlev var mı?


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

Yanıtlar:


315

Kurtarmaya Resig:

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

Uyarı : bazı VM'lerde maksimum bağımsız değişken sayısı 65535 kadar düşük olduğundan, dizinin bu kadar küçük olduğundan emin değilseniz bir for döngüsü kullanın.


15
Ah, ama şimdi sadece biraz çarpık bir şekilde yapıştırılmış SO Kalite Kalitesi var !
Shog9

2
FWIW, performans çözümünüzde bir faktörse, iyi performans gösterdiğinden emin olmak için kendi kolayca kodlanan işlevinizle karşılaştırıldığında bunu test ederim . Yerel uygulamanın daha hızlı olacağını varsayma eğilimindeyiz; aslında, applyçağrının maliyeti bunu kolayca yıkayabilir.
TJ Crowder

2
Dizi uzunluğum parametre sayısı sınırından büyükse ne olur?
lukas.pukenis

3
@CrescentFresh buna göre: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… , 65535 olarak kodlanmıştır. Buna göre: code.google.com/p/v8/issues/detail?id = 172 ve argümanların yığına doğru itildiği
bilgisiyle

9
Ayrıca, bu yöntem sağlam değildir. Diziniz, mamximum yığın boyutundan daha büyükse başarısız olurRangeError: Maximum call stack size exceeded.
Mark Lundin

197

Math.max öğesini çağırmak için uygula işlevini kullanabilirsiniz :

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

Nasıl çalışır?

Uygulama fonksiyonu bir dizi olarak sağlanan belirli bir bağlamda ve bağımsız değişkenler, ile, başka bir işlevi çağırmak için kullanılır. Min ve max işlevleri isteğe bağlı sayıda giriş argümanı alabilir: Math.max (val1, val2, ..., valN)

Yani, eğer ararsak:

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

Uygula işlevi aşağıdakileri yürütür:

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

İlk parametrenin, bağlamın, statik oldukları için bu işlevler için önemli olmadığını, bağlam olarak geçirilenlerden bağımsız olarak çalışacaklarını unutmayın.


2
Whoa çok çaba sarf ederek cevaplarınızı
veriyorsunuz

1
Bu harika. Peki dizi uzunluğum parametre boyut sınırını (fonksiyonun) aşarsa ne olur? Sonra ne ?
lukas.pukenis

1
Bu yanıtı diğerlerinden daha çok seviyorum çünkü her şeyin ne yaptığını ve nedenini açıklıyor. +1
Marvin

59

Yeni forma operatörü ile en kolay sözdizimi :

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

Kaynak: Mozilla MDN


2
Ancak, dizi çok fazla öğe içeriyorsa, hem yayılma (...) hem de uygulama başarısız olur veya yanlış sonucu döndürür developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Yeşil

@Yeşil FWIW, parametre sayısı sınırı 65536'dır (en azından Chrome'da) ([kaynak ( bugs.webkit.org/show_bug.cgi?id=80797)] ). Dizinizde 65536'dan fazla öğe varsa, bu yanıt çalışmaz.
9:43

4
65536 kimse için yeterli olmalı
vsync

41

Ben JS uzmanı değilim, ama bu yöntemlerin nasıl biriktiğini görmek istedim, bu yüzden bu benim için iyi bir uygulama oldu. Bu teknik performans bunları test etmek için doğru yolu olup olmadığını bilmiyorum, ama kodumda görebileceğiniz gibi, onları birbiri ardına koştum.

0'ıncı değeri sıralamak ve elde etmek en kötü yöntemdir (ve dizinizin sırasını değiştirir, bu istenilemez). Milyonlarca endeksten bahsetmediğiniz sürece diğerleri için fark göz ardı edilebilir.

100.000 dizinli rastgele sayılar dizisiyle beş çalışmanın ortalama sonuçları:

  • reduce çalıştırmak için 4.0392ms aldı
  • Math.max.apply aldı 3.3742ms çalıştırmak için
  • sıralama ve 0 değerini alma çalıştırmak için 67.4724ms aldı
  • Math.max içinde reduce () çalıştırmak için 6.5804ms aldı
  • özel findmax fonksiyon aldı 1.6102ms çalıştırmak için

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
Benim için bu soru için en iyi cevap bu.
rzelek

1
jsperf testsYukarıdakiler için yaptım
vsync

37

Ben daha büyük diziler (~ 100k elemanları) için, aslında for~% 30 daha iyi performans mütevazi bir döngü ile dizi yineleme için öder 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;
}

Deney sonuçları


3
FWIW, Chrome 31'de% 84'e çıktı.
Ilan Biala

31

Diziyi azalan sırada sıralayabilir ve ilk öğeyi alabilirsiniz:

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

4
Ben de sadece son öğeyi sıralamak ve alabilirsiniz varsayalım ...?
Shog9

@ Shog9: Evet, ancak karşılaştırma işlevini kendi başınıza belirtmeniz gerekir:sort(function(a,b){return b-a;})
Gumbo

9
Ah. Ben daha çok gibi düşünüyordum:[...].sort().pop()
Shog9 15

4
"numarayı bulmak sipariş-n alır, sıralama sipariş (n log n) ile sipariş (n kare) arasında, kullanılan sıralama algoritmasına bağlıdır" - webmasterworld.com/forum91/382.htm
Marco Luglio

2
Ayrıca, bunun istenen bir yan etki olabilecek veya olmayabilecek diziyi sıraladığını unutmayın. Uygulama çözümü daha iyi performans gösterir ve yan etkisi yoktur.
Caleb

28

Buna ne dersin:

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

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

console.log(largest);

İlk önce bu cevabı görseydim (şu anda listenin altında) iki saat kazanmış olurdum.
user139301

1
Math.max yaklaşımı muhtemelen en standarttır, ancak dizi çok büyük olduğunda (500K) yığın taşması alıyordum. Bu cevap hızlı ve etkilidir ve kendimi kullandığım cevaptır, bu yüzden bunu yanıtlıyorum.
Jay

8

Array.reduce kullanmaya ne dersiniz ?

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

Başlangıç ​​değeri olarak ayarlanmalıdır -Infinity.
Ja͢ck

@Jack, buna neden ihtiyaç var? tüm negatif sayılardan oluşan bir dizide bile geçerli bir sonuç alıyorum.
CodeToad

1
Dizinin boş olduğu uç durumdur.
Ja͢ck

5

Hemen hemen tüm cevaplar Math.max.apply()güzel ve züppe ama sınırlamaları olan kullanın.

İşlev argümanları, bir dezavantajı olan bir sınıra yerleştirilir. Yani diziniz sınırdan büyükse başarısız olurRangeError: Maximum call stack size exceeded.

Bir çağrı yığını boyutu bulmak için bu kodu kullandım:

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

Makinemdeki FireFox üzerinde en büyük olduğu kanıtlandı - 591519 . Bu, diziniz 591519'dan fazla öğe içeriyorsa RangeError ileMath.max.apply() sonuçlanacağı anlamına gelir .

Bu sorun için en iyi çözüm yinelemeli yöntemdir (kredi: 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];
}

Bu soru hakkında buradaki blogumda yazdım .


1
Bu adil değil. Cevabı burada istiyorum, SO'da, başka bir üçüncü taraf kaynağına başka bir bağlantı değil. Özellikle "buradaki her şey kötü, ama git, bak,
osa

@SergeyOrshanskiy yeni bir insigths ve çözümlerle güncellenmesi durumunda üçüncü bir tarafa bağlantı çok iyi çalışıyor. Ayrıca rahatsız hissetmeye gerek yok. İnsanlar sadece problemlerinizi çözmek istiyorlar. Ben de çözmek istedim, bu yüzden
blogumda yazdım


5

Maksimum ve minimum değerleri kolay ve manuel olarak bulmak. Bu kod daha hızlıdır Math.max.apply; Dizide 1000 bine kadar sayıyı denedim.

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()dizide yalnızca negatif sayılar varsa yanlış sonuç verir; findmin()boş bir dizi için yanlış sonuç verir.
Ja͢ck


3

Evet elbette var: Math.max.apply(null,[23,45,67,-45]) sonuç geri dönüyor 67;



1

Function.prototype.bindSargının size "tamamen doğal" bir işlev vererek yapılabileceğini unutmayın .

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

1

Ayrıca Arraybu işleve sahip olmak ve her dizinin bir parçası yapmak için genişletebilirsiniz .

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

console.log( myArray.max() );

1
Çok verimsiz.
Frank Schmitt

@FrankSchmitt, teşekkür ederim, katılıyorum. Orijinal cevap iyi bir çözüm değildi. Varsayılan olarak sırala, sayıları sıralamaz, öğelere dize olarak davranır. Cevabımı doğru sıralamaya sahip olacak şekilde düzenledi.
Izz

Demek istediğim bu değildi. Bir diziyi maksimumu bulmak için ayırmak, en azından N log N işlemlerini alırken, maksimumu bulmak N işlemlerinde yapılabilir.
Frank Schmitt

1

ForEach için de kullanabilirsiniz :

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

- kullanmak Array.prototype.reduce()harika!

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

burada acc = akümülatör ve val = akım değeri ;

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

console.log(a);


1

Bunu deneyebilirsin,

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

JS ile yeni başladım ama bu yöntemin iyi olacağını düşünüyorum:

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

arrayYalnızca negatif sayılar varsa bu sorun yaşayacaktır .
Teepeemm

0

Çok boyutlu bir dizideki en büyük sayıyı bulma

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;

Özellikle birden fazla başka yanıt varsa, kodunuza her zaman ayrıntılı bir açıklama eklemeniz önerilir. Bu neden farklı / daha iyi?
Bowdzone

@Bowdzone, yorum için teşekkürler. bu şekilde, sadece birkaç yöntem hakkında biraz bilgi sahibi olmanızı kolaylaştıran şey çok basittir.
Liveindream

Bu, en büyük sayıyı döndürmez, çok boyutlu dizideki her bir dizinin en büyük sayısının bir dizisini döndürür. Sen mesela eklemek gerekir var tmax = Math.max.apply(Math, max), ya da daha iyisi, bir döngü fonksiyonu örneğin bir kapağın kullanılmasına stackoverflow.com/a/54980012/7438857 . Bu değişiklikle, ayrı bir soruya daha iyi cevap verilir, "çok boyutlu bir dizideki en büyük sayıyı nasıl bulursunuz" veya stackoverflow.com/questions/32616910/… . WIP: jsfiddle.net/jamesray/3cLu9for/8 .
James Ray

stackoverflow.com/a/32617019/7438857 doğru soruya daha iyi bir cevaptır, ancak bu cevap yukarıdaki soruya cevap vermez, çok boyutlu bir dizideki her dizideki en büyük sayıyı döndürür.
James Ray

0

Bunu çalıştırın:

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

Ve şimdi [3,10,2].max()geri dönüşleri deneyin10


0

Bubble Sort kullanarak Maks ve Min değerini bulun

    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) Javascript dizileri zaten bir O (n log n) sıralama fonksiyonuna sahiptir. (2) Kabarcık sıralaması O (n ^ 2) 'dir. (3) Minimum ve maksimum değerleri bulmak O (n) 'dir.
Teepeemm

0

Bunu dene

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
Bu cevap, bu sayfadaki diğerlerin çoğundan önemli ölçüde farklı mı?
Teepeemm

0

@ Quasimondo'nun büyük ölçüde kaçırılmış gibi görünen yorumuna göre , aşağıda gösterildiği gibi en iyi performansa sahip gibi görünüyor: https://jsperf.com/finding-maximum-element-in-an-array . Not Söz konusu dizi için, performans önemli bir etkiye sahip olmayabilir iken, büyük diziler için performans daha önemli ve tekrar olur olarak kaydetti kullanılarak Math.max()dizi uzunluk da fazla 65535 Bkz ise yaptığı bile işi bu cevap .

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

Üçlü operatörler kullanarak nasıl yapılacağı konusunda özyinelemeli bir yaklaşım

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

Bir for/ofdöngü çözümü:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.