Wie kann ich einfach das Min- oder Max-Element eines JavaScript-Arrays erhalten?
Beispiel Pseudocode:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
javascript
HankH
quelle
quelle
...
) mitMath.max()
wie folgt aus :Math.max(...[2, 5, 16, 1])
. Siehe meine Antwort aus der MDN-Dokumentation .Math.max.apply(null, [2,5,16,1])
Antworten:
Wie wäre es, wenn Sie das integrierte Array-Objekt erweitern, um
Math.max
/Math.min
stattdessen zu verwenden:Hier ist eine JSFiddle .
Die Einbauten vermehren können mit anderen Bibliotheken verursachen Kollisionen (einige see), so können Sie mit nur bequemer
apply
‚ingMath.xxx()
direkt auf Ihrem Array:Angenommen, Ihr Browser unterstützt ECMAScript 6, können Sie alternativ den Spread-Operator verwenden, der ähnlich wie die
apply
Methode funktioniert :quelle
null
oderMath
oder{}
oder was auch immerapply()
odercall()
hat keinen Einfluss auf das Ergebnis.Math.max
verweist nicht und sollte auch nichtthis
intern referenzieren .Math.max.apply(null, $.makeArray(array));
.max
oder eine.min
Methode bietet . Perfekt realistisches Szenario: Sie verwenden diese Antwort. Im Jahr 2016 ES7 oder ES8 specArray.max
undArray.min
. Im Gegensatz zu dieser Version arbeiten sie mit Zeichenfolgen. Ihr zukünftiger Kollege versucht, mit der jetzt gut dokumentierten nativen.max()
Methode die alphabetisch neueste Zeichenfolge in einem Array abzurufen, erhält dies jedoch auf mysteriöse WeiseNaN
. Stunden später findet sie diesen Code, führt a ausgit blame
und verflucht Ihren Namen.Eine vollständige Diskussion finden Sie unter: http://aaroncrane.co.uk/2008/11/javascript_max_api/
quelle
Math.max.apply(Math, array)
undMath.max.apply(null, array)
? Der Blog sagt "... du musst auch redundant noch einmal sagen, wasmax
zuMath
... gehört", aber es scheint, dass ich das nicht tun muss (indem ich das erste Argument vonapply
as setzenull
).Math.max(a,b)
,Math
wird es alsthis
Wert übergeben, daher ist es möglicherweise sinnvoll, dasselbe zu tun, wenn Sie mit aufrufenapply
. AberMath.max
nicht die Verwendungthis
Wert, so können Sie übergeben , was von Ihnen gewünschten Wert.Für große Arrays (~ 10⁷ Elemente)
Math.min
undMath.max
beide erzeugen den folgenden Fehler in Node.js.Eine robustere Lösung besteht darin, nicht jedes Element zum Aufrufstapel hinzuzufügen, sondern stattdessen ein Array zu übergeben:
Wenn Sie sich Gedanken über die Geschwindigkeit machen, ist der folgende Code ~ 3-mal schneller
Math.max.apply
als auf meinem Computer. Siehe http://jsperf.com/min-and-max-in-array/2 .Wenn Ihre Arrays Zeichenfolgen anstelle von Zahlen enthalten, müssen Sie diese auch in Zahlen umwandeln. Der folgende Code macht das, aber er verlangsamt den Code auf meinem Computer ~ 10 Mal. Siehe http://jsperf.com/min-and-max-in-array/3 .
quelle
min
undmax
zum letzten Element zu und reduziere die Iterationen um 1 (while(--len)
);)very different results
Sie haben dies 5 Jahre späterreduce
Lösung die langsamste. Selbst wenn Sie mit einem Array arbeiten, das Millionen von Elementen enthält, ist es besser, den Standard für die Schleife zu verwenden . Siehe meine Antwort für mehr.Verwenden des Spread-Operators (ES6)
Code-Snippet anzeigen
quelle
If no arguments are given, the result is -∞.
tl; dr
MDN-Lösung
Die offiziellen MDN-Dokumente
Math.max()
behandeln dieses Problem bereits:Maximale Größe eines Arrays
Nach MDN die
apply
und Verbreitung Lösungen hatten eine Beschränkung von 65536 , die von der Grenze der maximalen Anzahl von Argumenten kam:Sie bieten sogar eine Hybridlösung, die im Vergleich zu anderen Lösungen keine wirklich gute Leistung aufweist. Weitere Informationen finden Sie im Leistungstest unten.
Im Jahr 2019 ist das tatsächliche Limit die maximale Größe des Aufrufstapels . Für moderne Chromium-basierte Desktop-Browser bedeutet dies, dass beim Finden von Min / Max mit
apply
oder Spread praktisch die maximale Größe für Arrays nur mit Zahlen ~ 120000 beträgt . Darüber hinaus kommt es zu einem Stapelüberlauf und der folgende Fehler wird ausgelöst:Mit dem folgenden Skript (basierend auf diesem Blog-Beitrag ) können Sie durch Abfangen dieses Fehlers das Limit für Ihre spezifische Umgebung berechnen.
Warnung! Das Ausführen dieses Skripts nimmt Zeit in Anspruch und kann je nach Leistung Ihres Systems Ihren Browser / Ihr System verlangsamen oder zum Absturz bringen!
Leistung auf großen Arrays
Basierend auf dem Test in EscapeNetscape 's Kommentar habe ich einige Benchmarks erstellt, die 5 verschiedene Methoden an einem Array nur mit Zufallszahlen mit 100000 Elementen testen .
Im Jahr 2019 zeigen die Ergebnisse, dass die Standardschleife (für die übrigens keine Größenbeschränkung gilt) überall die schnellste ist.
apply
und die Ausbreitung kommt dicht danach, dann viel später die Hybridlösung von MDNreduce
als die langsamste.Fast alle Tests ergaben die gleichen Ergebnisse, mit Ausnahme eines Tests, bei dem die Ausbreitung am langsamsten war.
Wenn Sie Ihr Array auf 1 Million Elemente erweitern, beginnen die Dinge zu brechen und Sie haben die Standardschleife als schnelle und
reduce
langsamere Lösung .JSPerf-Benchmark
JSBen Benchmark
JSBench.me Benchmark
Benchmark-Quellcode
Code-Snippet anzeigen
quelle
Math.max.apply(Math, arr)
maximalen Kompatibilität kompiliert .(...)
undapply
schlagen entweder fehl oder geben das falsche Ergebnis zurück, wenn das Array zu viele Elemente enthält. [...] Die Reduktionslösung hat dieses Problem nicht." Beim Testen von Chrome, FF, Edge und IE11 scheint dies der Fall zu sein OK für ein Array mit bis zu 100.000 Werten. (Getestet unter Win10 und den neuesten Browsern: Chrome 110k, Firefox 300k, Edge 400k, IE11 150k).Wenn Sie wie ich paranoid sind
Math.max.apply
(was bei großen Arrays gemäß MDN zu Fehlern führen kann ), versuchen Sie Folgendes:Oder in ES6:
Die anonymen Funktionen sind leider notwendig (anstatt zu verwenden,
Math.max.bind(Math)
weilreduce
nicht nura
undb
zu seiner Funktion, sondern auchi
und ein Verweis auf das Array selbst übergeben wird, müssen wir sicherstellen, dass wir nicht versuchen, diese auch aufzurufenmax
.quelle
Math.max(...array)
?apply
ist und daher dieselben Nachteile hat (maximale Argumentgrenze).function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
Math.min()
ohne Werte aufzurufen , gibt zurückInfinity
, sodass diese Funktionen verwendet werden könntenreduce(..., Infinity)
, um diesem Verhalten zu entsprechen. Ich bevorzuge es jedoch, eine Ausnahme auszulösen (wie es derzeit der Fall ist), da es wahrscheinlich ein Fehler ist, das Minimum eines leeren Arrays zu nehmen..apply
wird häufig verwendet, wenn die Absicht besteht, eine variable Funktion mit einer Liste von Argumentwerten aufzurufen, zDie
Math.max([value1[,value2, ...]])
Funktion gibt die größte von null oder mehr Zahlen zurück.Mit dieser
Math.max()
Methode können Sie kein Array übergeben. Wenn Sie eine Liste von Werten haben, von denen Sie die größten erhalten müssen, rufen Sie diese Funktion normalerweise mit Function.prototype.apply () auf , zDoch wie der ECMAScript 6 können Sie die Verwendung Spread Betreiber :
Mit dem Spread-Operator kann Folgendes wie folgt umgeschrieben werden:
Wenn Sie eine Funktion mit dem Variadic-Operator aufrufen, können Sie sogar zusätzliche Werte hinzufügen, z
Bonus:
Spread - Operator können Sie die Arrayliteral Syntax verwenden , um neue Felder in Situationen zu schaffen , in denen in ES5 Sie fallen zurück zu zwingenden Code benötigen würde, eine Kombination der Verwendung
push
,splice
etc.quelle
concat
von den meisten Programmierern verwendet, da Sie damit einen einzelnen Linienstil beibehalten können.Zwei Wege sind kürzer und einfacher:
Weg 1 :
Weg 2 :
quelle
0
Sie[0].concat(arr)
oder mit Spread-Syntax[0, ...arr]
(anstelle von 'arr') verwendenSie tun dies, indem Sie den Array-Typ erweitern:
Von hier aus verstärkt (von John Resig)
quelle
Eine einfache Lösung, um den Mindestwert für ein
Array
Element zu ermitteln, ist die Verwendung derArray
Prototypfunktionreduce
:oder mit der in JavaScript integrierten Funktion Math.Min () (danke @Tenflex):
Dies setzt
min
aufA[0]
und prüft dann,A[1]...A[n]
ob es strikt kleiner als der Strom istmin
. WennA[i] < min
dann aufmin
aktualisiert wirdA[i]
. Wenn alle Array-Elemente verarbeitet wurden,min
wird dies als Ergebnis zurückgegeben.BEARBEITEN : Position des Mindestwerts einschließen:
quelle
min
Wert zurückgegeben werden, sondern auch seine Position im Array?Andere haben bereits einige Lösungen angegeben, die sie erweitern
Array.prototype
. Alles, was ich in dieser Antwort möchte, ist zu klären, ob es sein sollteMath.min.apply( Math, array )
oder nichtMath.min.apply( null, array )
. Welcher Kontext sollte also verwendet werden,Math
odernull
?Bei der Übergabe
null
als Kontext anapply
wird der Kontext standardmäßig auf das globale Objekt (daswindow
Objekt bei Browsern) angewendet. DasMath
Objekt als Kontext zu übergeben wäre die richtige Lösung, aber es wird auch nicht schaden, es zu übergebennull
. Hier ist ein Beispiel, wennnull
beim Dekorieren derMath.max
Funktion Probleme auftreten können:Das Obige löst eine Ausnahme aus, da
this.foo
es alswindow.foo
, was ist , ausgewertet wirdundefined
. Wenn wir ersetzennull
mitMath
, wird es wie erwartet funktionieren und die Zeichenfolge „foo“ wird auf dem Bildschirm ausgegeben werden (Getestet habe ich diese mit Mozilla Rhino ).Sie können so ziemlich davon ausgehen, dass niemand so dekoriert hat,
Math.max
dass das Übergebennull
ohne Probleme funktioniert.quelle
Foo.staticMethod
und referenzierenthis
? Wäre das nicht ein Fehler im Design des Dekorateurs? (es sei denn natürlich waren sie wollen den globalen Bereich verweisen und wollen bleiben unabhängig von der JavaScript - Engine verwendet wird, zB Rhino).Math.max
, gemäß Spezifikation implementiert, wird nicht verwendetthis
. Wenn jemandMath.max
solche überschreibt , die er verwendetthis
, hat er dafür gesorgt, dass sein Verhalten gegen die Spezifikation verstößt, und Sie sollten scharfe Gegenstände auf ihn werfen. Sie sollten diese Möglichkeit nicht mehr codieren als die Möglichkeit, dass jemand getauscht hat,Math.max
undMath.min
für den Lulz.Noch eine Möglichkeit:
Verwendungszweck:
quelle
Alternative Methoden
Die Methoden
Math.min
undMath.max
sind rekursive Operationen, die dem Aufrufstapel der JS-Engine hinzugefügt werden, und höchstwahrscheinlich ein Absturz für ein Array, das eine große Anzahl von Elementen enthält(mehr als ~ 10⁷ Elemente, abhängig vom Browser des Benutzers).
Verwenden Sie stattdessen Folgendes:
Oder mit besserer Laufzeit:
Oder um sowohl Min als auch Max zu bekommen:
Oder mit noch besserer Laufzeit *:
* Getestet mit 1.000.000 Elementen:
Nur als Referenz: Die Laufzeit der ersten Funktion (auf meinem Computer) betrug 15,84 ms gegenüber der zweiten Funktion mit nur 4,32 ms.
quelle
Dies kann Ihren Zwecken entsprechen.
quelle
comparer
in einem bestimmten Umfang aufgerufen werden? Denn wie es ist, verweistthis[index]
esundefined
jedes Mal.Math.xxx
) im globalen Bereich ausgeführt wird ...https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/max
das hat bei mir funktioniert.
quelle
Ich bin überrascht, dass niemand die Reduktionsfunktion erwähnt hat.
quelle
Für große Arrays (~ 10⁷ Elemente)
Math.min
undMath.max
erzeugt einen RangeError (maximale Aufrufstapelgröße überschritten) in node.js.Für große Arrays ist eine schnelle und schmutzige Lösung:
quelle
Ich hatte das gleiche Problem, ich musste die Minimal- und Maximalwerte eines Arrays ermitteln, und zu meiner Überraschung gab es keine integrierten Funktionen für Arrays. Nachdem ich viel gelesen hatte, beschloss ich, die "Top 3" -Lösungen selbst zu testen:
Der Testcode war folgender:
Das Array A wurde mit 100.000 zufälligen Ganzzahlen gefüllt. Jede Funktion wurde 10.000 Mal unter Mozilla Firefox 28.0 auf einem Intel Pentium 4 2,99-GHz-Desktop mit Windows Vista ausgeführt. Die Zeiten sind in Sekunden angegeben und werden von der Funktion performance.now () abgerufen. Die Ergebnisse waren diese mit 3 Bruchstellen und Standardabweichung:
Die REDUCE-Lösung war 117% langsamer als die diskrete Lösung. Die APPLY-Lösung war die schlechtere, 2.118% langsamer als die diskrete Lösung. Außerdem funktioniert es, wie Peter bemerkte, nicht für große Arrays (ungefähr mehr als 1.000.000 Elemente).
Um die Tests abzuschließen, habe ich diesen erweiterten diskreten Code getestet:
Das Timing: Mittelwert = 0,218 s, SD = 0,094
Es ist also 35% langsamer als die einfache diskrete Lösung, ruft jedoch gleichzeitig sowohl den Maximal- als auch den Minimalwert ab (jede andere Lösung würde mindestens das Doppelte benötigen, um sie abzurufen). Sobald das OP beide Werte benötigte, wäre die diskrete Lösung die beste Wahl (selbst wenn zwei separate Funktionen, eine zur Berechnung des Maximums und eine zur Berechnung des Minimums, die zweitbeste, die REDUCE-Lösung, übertreffen würden).
quelle
Sie können die folgende Funktion überall in Ihrem Projekt verwenden:
Und dann können Sie die Funktionen aufrufen, die das Array übergeben:
quelle
Der folgende Code funktioniert für mich:
quelle
Iterieren Sie durch und behalten Sie dabei den Überblick.
Dadurch bleibt min / max null, wenn das Array keine Elemente enthält. Setzt min und max in einem Durchgang, wenn das Array Elemente enthält.
Sie können Array auch mit
range
der oben beschriebenen Methode erweitern, um die Wiederverwendung zu ermöglichen und die Lesbarkeit zu verbessern. Eine funktionierende Geige finden Sie unter http://jsfiddle.net/9C9fU/.Benutzt als
quelle
range
Funktion zu erweitern, die der beste Weg wäre, um sowohl das Min als auch das Max gleichzeitig zu erhalten, IMO - wie ich es mit einem Update meiner Antwort getan habe.Ich dachte, ich würde meine einfache und leicht verständliche Lösung teilen.
Für die min:
Und für das Maximum:
quelle
for…in
Aufzählungen für Arrays!Neben der Verwendung der mathematischen Funktionen max und min ist die integrierte Funktion sort () eine weitere zu verwendende Funktion: Los geht's
quelle
Einfaches Zeug, wirklich.
quelle
Hier ist eine Möglichkeit, den Maximalwert aus einem Array von Objekten abzurufen. Erstellen Sie eine Kopie (mit Slice), sortieren Sie die Kopie in absteigender Reihenfolge und greifen Sie zum ersten Element.
quelle
Verwenden von
Math.max()
oderMath.min()
Die folgende Funktion verwendet
Function.prototype.apply()
, um das maximale Element in einem numerischen Array zu finden.getMaxOfArray([1, 2, 3])
entspricht,Math.max(1, 2, 3)
kann jedochgetMaxOfArray()
für programmgesteuert erstellte Arrays jeder Größe verwendet werden.Oder mit dem neuen Spread-Operator wird es viel einfacher, das Maximum eines Arrays zu erhalten.
quelle
Die Lösung von ChaosPandion funktioniert, wenn Sie Prototyp verwenden. Wenn nicht, beachten Sie Folgendes:
Das Obige gibt NaN zurück, wenn ein Array-Wert keine Ganzzahl ist. Sie sollten daher einige Funktionen erstellen, um dies zu vermeiden. Andernfalls funktioniert dies.
quelle
Math
Objekt als Kontext verwenden?Wenn Sie die Bibliothek sugger.js verwenden , können Sie wie vorgeschlagen arr.min () und arr.max () schreiben . Sie können auch Min- und Max-Werte von nicht numerischen Arrays abrufen.
Beispiele:
Bibliotheken wie Lo-Dash und underscore.js bieten ebenfalls ähnliche leistungsstarke Min- und Max-Funktionen:
Beispiel aus Lo-Dash:
quelle
quelle
Versuchen
Code-Snippet anzeigen
Für Math.min / max (+ anwenden) erhalten wir folgende Fehlermeldung:
Code-Snippet anzeigen
quelle