Wie finde ich die größte Anzahl in einem JavaScript-Array?


206

Ich habe ein einfaches JavaScript-Array-Objekt, das einige Zahlen enthält.

[267, 306, 108]

Gibt es eine Funktion, die die größte Zahl in diesem Array findet?


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

Antworten:


315

Resig zur Rettung:

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

Warnung : Da die maximale Anzahl von Argumenten auf einigen VMs nur 65535 beträgt , verwenden Sie eine for-Schleife, wenn Sie nicht sicher sind, ob das Array so klein ist.


15
Ah, aber jetzt ist der SO-Aufkleber der Qualität nur leicht schief angebracht!
Shog9

2
FWIW, wenn Leistung ein Faktor in Ihrer Lösung ist, würde ich dies im Vergleich zu Ihrer eigenen einfach zu codierenden Funktion testen, um sicherzustellen, dass sie gut funktioniert. Wir gehen davon aus, dass die native Implementierung schneller sein wird. Tatsächlich können die Kosten des applyAnrufs dies sehr leicht auswaschen.
TJ Crowder

2
Was ist, wenn meine Array-Länge größer als die Parameteranzahl ist?
lukas.pukenis

3
@CrescentFresh laut diesem: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ist es fest auf 65535 codiert. Demnach: code.google.com/p/v8/issues/detail?id = 172 und durch das Wissen, dass Argumente auf Stapel geschoben werden, wissen wir, dass es nicht unbegrenzt ist
lukas.pukenis

9
Auch diese Methode ist nicht robust. Es schlägt fehl, wenn Ihr Array größer als die maximale Stapelgröße ist, was zuRangeError: Maximum call stack size exceeded.
Mark Lundin

197

Mit der Apply- Funktion können Sie Math.max aufrufen :

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

Wie es funktioniert?

Die Apply- Funktion wird verwendet, um eine andere Funktion mit einem bestimmten Kontext und Argumenten aufzurufen, die als Array bereitgestellt werden. Die Funktionen min und max können eine beliebige Anzahl von Eingabeargumenten annehmen: Math.max (val1, val2, ..., valN)

Also, wenn wir anrufen:

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

Die Apply-Funktion wird ausgeführt:

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

Beachten Sie, dass der erste Parameter, der Kontext, für diese Funktionen nicht wichtig ist, da sie statisch sind und unabhängig davon funktionieren, was als Kontext übergeben wird.


2
Whoa Sie setzen Ihre Antworten mit viel Mühe auf: D
ShrekOverflow

1
Das ist großartig. Was aber, wenn meine Array-Länge die Parametergrößenbeschränkung (der Funktion) überschreitet? Was dann ?
lukas.pukenis

1
Ich mag diese Antwort besser als die anderen, weil sie erklärt, was alles tut und warum. +1
Marvin

59

Die einfachste Syntax mit dem neuen Spread-Operator :

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

Quelle: Mozilla MDN


2
Sowohl Spread (...) als auch Apply schlagen jedoch fehl oder geben das falsche Ergebnis zurück, wenn das Array zu viele Elemente enthält. Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Green

@ Green FWIW, die Parameteranzahl beträgt 65536 (zumindest in Chrome) ([source ( bugs.webkit.org/show_bug.cgi?id=80797)] ). Wenn Ihr Array also mehr als 65536 Elemente enthält, funktioniert diese Antwort nicht.
mgthomas99

4
65536 sollte für jeden genug sein
vsync

41

Ich bin kein JS-Experte, aber ich wollte sehen, wie sich diese Methoden stapeln, daher war dies eine gute Praxis für mich. Ich weiß nicht, ob dies technisch der richtige Weg ist, um diese zu testen, aber ich habe sie einfach direkt nacheinander ausgeführt, wie Sie in meinem Code sehen können.

Das Sortieren und Abrufen des 0. Werts ist bei weitem die schlechteste Methode (und ändert die Reihenfolge Ihres Arrays, was möglicherweise nicht wünschenswert ist). Für die anderen ist der Unterschied vernachlässigbar, es sei denn, Sie sprechen von Millionen von Indizes.

Durchschnittliche Ergebnisse von fünf Läufen mit einem 100.000-Index-Array von Zufallszahlen:

  • nahm reduzieren 4.0392ms zu laufen
  • Math.max.apply nahm 3.3742ms zu laufen
  • Sortieren und immer die 0 - te Wert nahm 67.4724ms zu laufen
  • Math.max innerhalb reduzieren () nahm 6.5804ms zu laufen
  • benutzerdefinierte FindMax Funktion nahm 1.6102ms zu laufen

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
Für mich ist dies die beste Antwort auf diese Frage.
Rzelek

1
Ich habe jsperf testsfür die oben genannten gemacht
vsync

37

Ich habe festgestellt, dass es sich für größere Arrays (~ 100.000 Elemente) tatsächlich lohnt, das Array einfach mit einer bescheidenen forSchleife zu iterieren und eine um ~ 30% bessere Leistung zu erzielen als 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;
}

Benchmark-Ergebnisse


3
FWIW, kommt jetzt auf Chrome 31 zu 84% heraus.
Ilan Biala

31

Sie können das Array in absteigender Reihenfolge sortieren und das erste Element erhalten:

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

4
Ich würde annehmen, Sie könnten auch nur den letzten Artikel sortieren und bekommen ...?
Shog9

@ Shog9: Ja, aber Sie müssten die Vergleichsfunktion selbst festlegen:sort(function(a,b){return b-a;})
Gumbo

9
Ah. Ich dachte eher wie:[...].sort().pop()
Shog9

4
"Das Finden der Nummer erfordert order-n, das Sortieren dauert zwischen order (n log n) und order (n im Quadrat), abhängig vom verwendeten Sortieralgorithmus" - webmasterworld.com/forum91/382.htm
Marco Luglio

2
Denken Sie auch daran, dass dies das Array sortiert, was ein gewünschter Nebeneffekt sein kann oder nicht. Die Anwendung Lösung ist leistungsfähiger und hat keine Nebenwirkungen.
Caleb

28

Wie wäre es damit:

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

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

console.log(largest);

Hätte ich diese Antwort zuerst gesehen (derzeit am Ende der Liste), hätte ich zwei Stunden gespart.
user139301

1
Der Math.max-Ansatz ist wahrscheinlich der Standardansatz, aber ich hatte einen Stapelüberlauf, als das Array zu groß war (500 KB). Diese Antwort ist schnell und effizient und die, die ich letztendlich selbst verwendet habe, also stimme ich dieser zu.
Jay

8

Wie wäre es mit Array.reduce ?

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

Der Anfangswert sollte auf gesetzt sein -Infinity.
Ja͢ck

@ Jack, warum wird das benötigt? Selbst mit einem Array aller negativen Zahlen erhalte ich ein gültiges Ergebnis.
CodeToad

1
Dies ist der Randfall, bei dem das Array leer ist.
Ja͢ck

5

Fast alle Antworten verwenden, Math.max.apply()was nett und gut ist, aber Einschränkungen hat.

Funktionsargumente werden auf einen Stapel gelegt, der einen Nachteil hat - eine Grenze. Wenn Ihr Array also größer als das Limit ist, schlägt es mit fehlRangeError: Maximum call stack size exceeded.

Um eine Call-Stack-Größe zu finden, habe ich diesen Code verwendet:

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

Es erwies sich unter FireFox auf meinem Computer als das größte - 591519 . Wenn Ihr Array mehr als 591519 Elemente enthält, Math.max.apply()führt dies zu RangeError .

Die beste Lösung für dieses Problem ist der iterative Weg (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];
}

Ich habe über diese Frage in meinem Blog hier geschrieben .


1
Das ist nicht fair. Ich möchte die Antwort hier auf SO, nicht auf einen anderen Link zu einer anderen Ressource eines Drittanbieters. Besonders wenn es mit "alles hier ist schlecht, aber geh, schau, es ist so toll auf meinem Blog ..." kombiniert
osa

@SergeyOrshanskiy Ein Link zu einem Drittanbieter funktioniert sehr gut, falls er mit neuen Erkenntnissen und Lösungen aktualisiert wird. Auch keine Notwendigkeit, sich beleidigt zu fühlen. Die Leute wollen auch nur Ihre Probleme lösen. Ich wollte es auch lösen, also schrieb ich darüber in meinem Blog
lukas.pukenis

5

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max

const inputArray = [ 1, 3, 4, 9, 16, 2, 20, 18];
const maxNumber = Math.max(...inputArray);
console.log(maxNumber);


2
Sowohl Spread (...) als auch Apply schlagen jedoch fehl oder geben das falsche Ergebnis zurück, wenn das Array zu viele Elemente enthält. Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Green

5

Das einfache und manuelle Finden von Max- und Min-Werten. Dieser Code ist viel schneller als Math.max.apply; Ich habe bis zu 1000k Zahlen im Array ausprobiert.

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()gibt das falsche Ergebnis aus, wenn das Array nur negative Zahlen enthält; findmin()gibt das falsche Ergebnis für ein leeres Array aus.
Ja͢ck


3

Ja, natürlich gibt es: Math.max.apply(null,[23,45,67,-45]) und das Ergebnis kehrt zurück 67;



1

Vergessen Sie nicht, dass der Wrap durchgeführt werden kann Function.prototype.bind, sodass Sie eine "all-native" Funktion erhalten .

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

1

Sie können Arraydiese Funktion auch erweitern und zu einem Teil jedes Arrays machen.

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

console.log( myArray.max() );

1
Schrecklich ineffizient.
Frank Schmitt

@FrankSchmitt, danke, ich stimme zu. Die ursprüngliche Antwort war keine gute Lösung. Standardmäßig sortieren sortiert keine Zahlen, sondern behandelt Elemente als Zeichenfolgen. Ich habe meine Antwort bearbeitet, um die richtige Sortierung zu erhalten.
Izz

Das war nicht mein Punkt. Das Sortieren eines Arrays zum Ermitteln des Maximums ist per se schrecklich ineffizient, da mindestens N log N Operationen erforderlich sind, während das Ermitteln des Maximums in N Operationen erfolgen kann.
Frank Schmitt


1

Verwenden - Array.prototype.reduce()ist cool!

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

wobei acc = Akkumulator und val = aktueller Wert ;

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

console.log(a);


1

Sie können dies versuchen,

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

Ich habe gerade mit JS angefangen, aber ich denke, diese Methode wäre gut:

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

Dies hat Probleme, wenn arraynur negative Zahlen enthalten sind.
Teepeemm

0

Suchen Sie die größte Zahl in einem mehrdimensionalen Array

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;

Es ist immer ratsam, Ihrem Code eine ausführliche Erklärung hinzuzufügen, insbesondere wenn bereits mehrere andere Antworten vorliegen. Warum ist das anders / besser?
Bowdzone

@ Bowdzone, danke für den Kommentar. Dieser Weg ist sehr einfach, was es einfach macht, mit ein wenig Wissen über nur wenige Methoden zu verstehen.
Liveindream

Dies gibt nicht die größte Zahl zurück, sondern ein Array mit der größten Anzahl jedes Arrays im mehrdimensionalen Array. Sie müssten z. B. var tmax = Math.max.apply(Math, max)oder noch besser einen Verschluss einer Schleifenfunktion hinzufügen, z. B. in stackoverflow.com/a/54980012/7438857 . Mit dieser Änderung wird besser auf eine separate Frage geantwortet, wie Sie "die größte Zahl in einem mehrdimensionalen Array finden" oder unter stackoverflow.com/questions/32616910/… . WIP: jsfiddle.net/jamesray/3cLu9for/8 .
James Ray

stackoverflow.com/a/32617019/7438857 ist eine bessere Antwort auf die richtige Frage. Diese Antwort beantwortet zwar nicht die obige Frage, gibt jedoch die größte Zahl in jedem Array innerhalb eines mehrdimensionalen Arrays zurück.
James Ray

0

Führen Sie Folgendes aus:

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

Und jetzt versuchen Sie es mit [3,10,2].max()Retouren10


0

Finden Sie den Max- und Min-Wert mit 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) Javascript-Arrays haben bereits eine O (n log n) -Sortierfunktion. (2) Die Blasensortierung ist O (n ^ 2). (3) Das Finden von min und max ist O (n).
Teepeemm

0

Versuche dies

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
Unterscheidet sich diese Antwort wesentlich von vielen anderen auf dieser Seite?
Teepeemm

0

Gemäß dem Kommentar von @ Quasimondo , der anscheinend weitgehend übersehen wurde, scheint das Folgende die beste Leistung zu haben, wie hier gezeigt: https://jsperf.com/finding-maximum-element-in-an-array . Beachten Sie, dass die Leistung für das betreffende Array möglicherweise keinen signifikanten Effekt hat, bei großen Arrays jedoch die Leistung an Bedeutung gewinnt. Wie bereits erwähnt , Math.max()funktioniert die Verwendung nicht einmal, wenn die Array-Länge mehr als 65535 beträgt. Siehe auch diese Antwort .

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

Ein rekursiver Ansatz zur Verwendung ternärer Operatoren

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

One- for/ofLoop-Lösung:

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.