Wie kann ich leicht erhalten die minimale oder maximale Element eines JavaScript-Array?
Beispiel Pseudocode:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
Wie kann ich leicht erhalten die minimale oder maximale Element eines JavaScript-Array?
Beispiel Pseudocode:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
Eine einfache Lösung zur Ermittlung des Mindestwerts über eine Array
von Elementen ist die Verwendung der Array
Prototyp-Funktion reduce
:
A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min ? val : min, A[0]); // returns -9
oder mit der in JavaScript integrierten Funktion Math.Min() (danke @Tenflex):
A.reduce((min,val) => Math.min(min,val), A[0]);
Dies setzt min
a A[0]
und prüft dann auf A[1]...A[n]
ob er genau kleiner ist als der aktuelle min
. Wenn A[i] < min
dann min
wird aktualisiert zu A[i]
. Wenn alle Array-Elemente verarbeitet wurden, min
wird als Ergebnis zurückgegeben.
EDIT : Position des Mindestwertes einbeziehen:
A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min._min ? {_min: val, _idx: min._curr, _curr: min._curr + 1} : {_min: min._min, _idx: min._idx, _curr: min._curr + 1}, {_min: A[0], _idx: 0, _curr: 0}); // returns { _min: -9, _idx: 2, _curr: 6 }
Für eine prägnante, moderne Lösung kann man eine reduce
Operation über das Array, wobei die aktuellen Minimal- und Maximalwerte festgehalten werden, so dass das Array nur einmal durchlaufen wird (was optimal ist). Destrukturierungsauftrag wird hier der Kürze halber verwendet.
let array = [100, 0, 50];
let [min, max] = array.reduce(([prevMin,prevMax], curr)=>
[Math.min(prevMin, curr), Math.max(prevMax, curr)], [Infinity, -Infinity]);
console.log("Min:", min);
console.log("Max:", max);
Um nur das Minimum oder Maximum zu finden, können wir eine Reduktionsoperation auf die gleiche Weise durchführen, aber wir müssen nur den vorherigen optimalen Wert im Auge behalten. Diese Methode ist besser als die Verwendung von apply
da sie keine Fehler verursacht, wenn das Array zu groß für den Stack ist.
const arr = [-1, 9, 3, -6, 35];
//Only find minimum
const min = arr.reduce((a,b)=>Math.min(a,b), Infinity);
console.log("Min:", min);//-6
//Only find maximum
const max = arr.reduce((a,b)=>Math.max(a,b), -Infinity);
console.log("Max:", max);//35
Andere haben bereits einige Lösungen genannt, mit denen sie die Array.prototype
. Ich möchte mit dieser Antwort lediglich klären, ob es sich um Math.min.apply( Math, array )
o Math.min.apply( null, array )
. Welcher Kontext sollte also verwendet werden? Math
o null
?
Beim Passieren null
als Kontext zu apply
ist, dann wird der Kontext standardmäßig auf das globale Objekt (die window
Objekt im Falle von Browsern). Die Übergabe des Math
Objekt als Kontext wäre die richtige Lösung, aber es schadet auch nicht, wenn man null
entweder. Hier ist ein Beispiel, wenn null
Probleme verursachen könnte, wenn die Dekoration der Math.max
Funktion:
// decorate Math.max
(function (oldMax) {
Math.max = function () {
this.foo(); // call Math.foo, or at least that's what we want
return oldMax.apply(this, arguments);
};
})(Math.max);
Math.foo = function () {
print("foo");
};
Array.prototype.max = function() {
return Math.max.apply(null, this); // <-- passing null as the context
};
var max = [1, 2, 3].max();
print(max);
Das obige Beispiel löst eine Ausnahme aus, weil this.foo
wird bewertet als window.foo
das ist undefined
. Wenn wir ersetzen null
con Math
funktioniert alles wie erwartet und die Zeichenkette "foo" wird auf dem Bildschirm ausgegeben (ich habe dies mit Mozilla Rhino ).
Sie können ziemlich sicher davon ausgehen, dass niemand die Math.max
Also, vorbei an null
funktioniert ohne Probleme.
Das ist richtig. Aber warum sollte jemand eine Wohnung dekorieren Foo.staticMethod
und Hinweis this
? Wäre das nicht ein Fehler im Design des Dekorateurs? (es sei denn natürlich, sie waren will um auf den globalen Bereich zu verweisen, und wollen um unabhängig von der verwendeten JavaScript-Engine (z. B. Rhino) zu bleiben.
Die Spezifikation ist eindeutig festgelegt, welche spezifizierten Funktionen sich auf "die este Wert" (dieser Satz taucht in der Tat 125 Mal in der Spezifikation auf). Math.max
die laut Spezifikation implementiert ist, verwendet nicht this
. Wenn sich jemand darüber hinwegsetzt Math.max
so, dass es die this
dann haben sie dafür gesorgt, dass sein Verhalten gegen die Spezifikation verstößt, und Sie sollten mit scharfen Gegenständen nach ihm werfen. Sie sollten diese Möglichkeit ebenso wenig in Ihrem Code umgehen, wie Sie die Möglichkeit umgehen würden, dass jemand die Math.max
y Math.min
für die Lachmuskeln.
Kann jemand erklären, wie das funktioniert? Das ist ziemlich genial. Verstehe ich das richtig: arrayMax ist eine Funktion und wir binden etwas an eine Eigenschaft des Prototyps? Was ist dieses apply.bind und hat es jeder Prototyp?
Achtung: reduce() wird ab IE9 unterstützt, siehe developer.mozilla.org/de-US/docs/Web/JavaScript/Reference/
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
178 Stimmen
Anmerkung: Mit ECMAScript 6 können Sie die neue Spread-Operator (drei Punkte:
...
) mitMath.max()
wie diese:Math.max(...[2, 5, 16, 1])
. Siehe meine Antwort aus dem MDN-Dokumentation .0 Stimmen
Hier ein Benchmark für einen Geschwindigkeitsvergleich der gebräuchlichsten Vorgehensweisen: jsben.ch/#/1QuTg
0 Stimmen
Ohne ES6
Math.max.apply(null, [2,5,16,1])
2 Stimmen
In ES6 können sowohl das Maximum als auch das Minimum wie folgt ermittelt werden mit nur einem
reduce
aufrufen .0 Stimmen
Die Lösung von @totymedli, den Spread-Operator zu verwenden, ist keine gute Idee. Wenn das Array zu groß ist, führt dies zu einer Stack Overflow Exception (zu viele Parameter werden an die Funktion übergeben). Eine viel bessere Idee ist die Verwendung von
reduce
1 Stimmen
@AronFiechter Haben Sie meine Antwort tatsächlich gelesen? Ich erkläre alle Optionen sehr detailliert mit Codebeispielen und Benchmarks. Die Größe des Aufrufstapels ist nur dann ein Problem, wenn Ihre Arrays eine Größe von mehr als 100000 haben. Der Aufrufstapel muss zwar berücksichtigt werden, aber in den meisten Fällen ist er kein Problem und der prägnantere Code überwiegt die Nachteile.
1 Stimmen
Dieser Aufrufstapel kann ein Problem darstellen. Es gibt eine HackerRank-Frage, bei der Min und Max gefunden werden müssen, und die Tests laufen unter einem Limit von 10 Sekunden. Die von HackerRank für den 9. bis 14. Test übergebenen Arrays haben eine Länge von mehr als 100.000 und schlagen fehl, wenn die reduzierte Lösung in der Antwort unten verwendet wird. Die for-Schleife wird für einige
0 Stimmen
Utilice
...
(Spread-Operator):const maxValue = Math.max(...array))