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
Wenn Sie wie ich paranoid sind, was die Verwendung von Math.max.apply
(was bei großen Arrays zu Fehlern führen kann) laut MDN ), versuchen Sie dies:
function arrayMax(array) {
return array.reduce(function(a, b) {
return Math.max(a, b);
});
}
function arrayMin(array) {
return array.reduce(function(a, b) {
return Math.min(a, b);
});
}
Oder, in ES6:
function arrayMax(array) {
return array.reduce((a, b) => Math.max(a, b));
}
function arrayMin(array) {
return array.reduce((a, b) => Math.min(a, b));
}
Die anonymen Funktionen sind leider notwendig (statt der Verwendung von Math.max.bind(Math)
denn reduce
nicht einfach passieren a
y b
zu seiner Funktion, sondern auch i
und einen Verweis auf das Array selbst, also müssen wir sicherstellen, dass wir nicht versuchen, die max
auch auf diese.
Ihr ES6-Beispiel, gibt es einen Grund, warum nicht einfach zurückgeben Math.max(...array)
?
@WojciechBednarski diese Seite scheint zu suggerieren, dass die Verwendung des Spread-Operators dasselbe ist wie die Übergabe eines Arrays an apply
und hat daher die gleichen Nachteile (Höchstgrenze für Argumente).
Vielen Dank dafür. Nur können Sie korrigieren fehlende Klammer nach reduzieren: function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
Le site Math.min
y Math.max
sind großartige Methoden, um das Minimum und das Maximum aus einer Sammlung von Gegenständen herauszuholen, aber es ist wichtig, sich einiger Hohlräume bewusst zu sein, die damit einhergehen können.
Die Verwendung mit einem Array, das eine große Anzahl von Elementen enthält (mehr als ~10 Elemente, abhängig vom Browser des Benutzers), wird höchstwahrscheinlich Absturz und geben die folgende Fehlermeldung aus:
const arr = Array.from(Array(1000000).keys());
Math.min(arr);
Math.max(arr);
Ungefangener RangeError: Maximale Größe des Aufrufstapels überschritten
UPDATE
Neueste Browser könnten zurückkehren NaN
stattdessen. Das könnte ein besserer Weg sein, um mit Fehlern umzugehen, löst aber das Problem noch nicht.
Verwenden Sie stattdessen etwas wie dieses:
function maxValue(arr) {
return arr.reduce((max, val) => max > val ? max : val)
}
Oder mit besserer Laufzeit:
function maxValue(arr) {
let max = arr[0];
for (let val of arr) {
if (val > max) {
max = val;
}
}
return max;
}
Oder um sowohl Min als auch Max zu erhalten:
function getMinMax(arr) {
return arr.reduce(({min, max}, v) => ({
min: min < v ? min : v,
max: max > v ? max : v,
}), { min: arr[0], max: arr[0] });
}
Oder mit noch besseren Laufzeiten*:
function getMinMax(arr) {
let min = arr[0];
let max = arr[0];
let i = arr.length;
while (i--) {
min = arr[i] < min ? arr[i] : min;
max = arr[i] > max ? arr[i] : max;
}
return { min, max };
}
* Getestet mit 1.000.000 Artikeln:
Nur als Anhaltspunkt: Die Laufzeit der 1. Funktion (auf meinem Rechner) betrug 15,84 ms gegenüber der 2. Funktion mit nur 4,32 ms.
@RicardoNolde Leider ändert das Verbreiten des Arrays nichts an der Funktionsweise der Math.min/max-Funktionen (getestet mit Chrome v91). Wenn das bei Ihnen funktioniert, teilen Sie bitte mit, welchen Browser/Version Sie verwenden.
Entschuldigung, ich hätte mich deutlicher ausdrücken sollen. Die NaN
Problem auftritt, weil Sie ein gerades Array übergeben. In den Browsern, die ich getestet habe, gibt es immer NaN
; das kann durch die Aufteilung des Feldes gelöst werden. Das andere Problem, das Sie angesprochen haben - die maximale Größe des Aufrufstapels - gilt immer noch, unabhängig von der Verteilung.
Passen Sie auf, wenn das Feld leer ist - Sie erhalten negative Unendlichkeit, was vielleicht nicht das ist, was Sie wollen. Wenn Sie lieber 0
können Sie [0].concat(arr)
oder mit gespreizter Syntax [0, ...arr]
(anstelle von 'arr')
.apply
wird häufig verwendet, wenn eine variable Funktion mit einer Liste von Argumentwerten aufgerufen werden soll, z. B.
Le site Math.max([value1[,value2, ...]])
Funktion gibt die größte von null oder mehr Zahlen zurück.
Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20
Le site Math.max()
Methode ist es nicht möglich, ein Array zu übergeben. Wenn Sie eine Liste von Werten haben, von denen Sie den größten abrufen müssen, würden Sie diese Funktion normalerweise mit Function.prototype.apply() z.B.
Math.max.apply(null, [10, 20]); // 20
Math.max.apply(null, [-10, -20]); // -10
Math.max.apply(null, [-10, 20]); // 20
Allerdings ist ab dem ECMAScript 6 können Sie die Spread-Operator :
Mit dem Spreizungsoperator kann ein Ausdruck an Stellen erweitert werden, an denen mehrere Argumente (bei Funktionsaufrufen) oder mehrere Elemente (bei Array-Literalen) erwartet werden.
Mit Hilfe des Spreizungsoperators lässt sich die obige Rechnung wie folgt umschreiben:
Math.max(...[10, 20]); // 20
Math.max(...[-10, -20]); // -10
Math.max(...[-10, 20]); // 20
Wenn Sie eine Funktion mit dem variadischen Operator aufrufen, können Sie sogar zusätzliche Werte hinzufügen, z. B.
Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50
Bonus:
Spread-Operator können Sie die Array-Literal-Syntax verwenden, um neue Arrays in Situationen zu erstellen, in denen Sie in ES5 auf imperativen Code zurückgreifen müssten, indem Sie eine Kombination aus push
, splice
, usw.
let foo = ['b', 'c'];
let bar = ['a', ...foo, 'd', 'e']; // ['a', 'b', 'c', 'd', 'e']
Sie tun dies, indem Sie den Typ Array erweitern:
Array.max = function( array ){
return Math.max.apply( Math, array );
};
Array.min = function( array ){
return Math.min.apply( Math, array );
};
Erhöht von aquí (von John Resig)
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))