Comment puis-je obtenir facilement l'élément min ou max d'un tableau JavaScript?
Exemple Psuedocode:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
Pourquoi ne pas augmenter l’objet Array intégré à utiliser Math.max
/ Math.min
à la place:
_Array.prototype.max = function() {
return Math.max.apply(null, this);
};
Array.prototype.min = function() {
return Math.min.apply(null, this);
};
_
Voici un JSFiddle.
Augmenter les fonctions intégrées peut provoquer des conflits avec d'autres bibliothèques (certaines voir), vous pouvez donc être plus à l'aise avec juste apply
'ing Math.xxx()
directement dans votre tableau:
_var min = Math.min.apply(null, arr),
max = Math.max.apply(null, arr);
_
Sinon, en supposant que votre navigateur prenne en charge ECMAScript 6, vous pouvez utiliser le opérateur qui fonctionne de la même manière que la méthode apply
:
_var min = Math.min( ...arr ),
max = Math.max( ...arr );
_
var max_of_array = Math.max.apply(Math, array);
Pour une discussion complète, voir: http://aaroncrane.co.uk/2008/11/javascript_max_api/
Pour les tableaux de grande taille (~ 10⁷ éléments), Math.min
et Math.max
produisent tous les deux l'erreur suivante dans Node.js.
RangeError: taille maximale de la pile d'appels dépassée
Une solution plus robuste consiste à ne pas ajouter chaque élément à la pile d'appels, mais à transmettre un tableau:
function arrayMin(arr) {
return arr.reduce(function (p, v) {
return ( p < v ? p : v );
});
}
function arrayMax(arr) {
return arr.reduce(function (p, v) {
return ( p > v ? p : v );
});
}
Si vous êtes préoccupé par la vitesse, le code suivant est environ 3 fois plus rapide que Math.max.apply
est sur mon ordinateur. Voir http://jsperf.com/min-and-max-in-array/2 .
function arrayMin(arr) {
var len = arr.length, min = Infinity;
while (len--) {
if (arr[len] < min) {
min = arr[len];
}
}
return min;
};
function arrayMax(arr) {
var len = arr.length, max = -Infinity;
while (len--) {
if (arr[len] > max) {
max = arr[len];
}
}
return max;
};
Si vos tableaux contiennent des chaînes au lieu de nombres, vous devez également les contraindre à des nombres. C'est ce que fait le code ci-dessous, mais cela le ralentit environ 10 fois sur ma machine. Voir http://jsperf.com/min-and-max-in-array/ .
function arrayMin(arr) {
var len = arr.length, min = Infinity;
while (len--) {
if (Number(arr[len]) < min) {
min = Number(arr[len]);
}
}
return min;
};
function arrayMax(arr) {
var len = arr.length, max = -Infinity;
while (len--) {
if (Number(arr[len]) > max) {
max = Number(arr[len]);
}
}
return max;
};
Utilisation de l'opérateur de propagation (ES6)
Math.max(...array); // the same with "min" => Math.min(...array);
const array = [10, 2, 33, 4, 5];
console.log(
Math.max(...array)
)
// For regular arrays:
var max = Math.max(...arrayOfNumbers);
// For arrays with tens of thousands of items:
let max = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
if (testArray[i] > max) {
max = testArray[i];
}
}
Le documentation MDN officielle sur Math.max()
couvre déjà ce problème:
La fonction suivante utilise Function.prototype.apply () pour rechercher l'élément maximal dans un tableau numérique.
getMaxOfArray([1, 2, 3])
est équivalent àMath.max(1, 2, 3)
, mais vous pouvez utilisergetMaxOfArray()
sur des tableaux construits par programme de toute taille.function getMaxOfArray(numArray) { return Math.max.apply(null, numArray); }
Ou avec le nouveau opérateur de propagation , obtenir le maximum d'un tableau devient beaucoup plus facile.
var arr = [1, 2, 3]; var max = Math.max(...arr);
Selon MDN la apply
et les solutions étendues avaient une limite de 65 536 qui provenait de la limite du nombre maximal d'arguments:
Mais attention: en appliquant de cette manière, vous courez le risque de dépasser la limite de longueur d'argument du moteur JavaScript. Les conséquences de l'application d'une fonction avec trop d'arguments (pensez plus que des dizaines d'arguments) varient d'un moteur à l'autre (. JavaScriptCore a une limite d'arguments codée en dur de 65 536 ), car la limite (même la nature de tout comportement de pile excessivement volumineuse) n’est pas spécifiée. Certains moteurs lanceront une exception. Plus pernicieusement, d'autres limiteront arbitrairement le nombre d'arguments réellement transmis à la fonction appliquée. Pour illustrer ce dernier cas: si un tel moteur avait une limite de quatre arguments (les limites réelles sont bien entendu nettement plus élevées), ce serait comme si les arguments 5, 6, 2, 3 avaient été passés pour s'appliquer dans les exemples ci-dessus, plutôt que le tableau complet.
Ils fournissent même une solution hybride qui n’a pas vraiment de bonnes performances par rapport à d’autres solutions. Voir le test de performance ci-dessous pour plus d'informations.
En 2019, la limite réelle est la taille maximale de la pile d'appels . Pour les navigateurs de bureau modernes basés sur Chromium, cela signifie que lorsqu'il s'agit de trouver min/max avec apply
ou de se propager, , la taille maximale des tableaux à chiffres uniquement est de ~ 120000 . Au-dessus de cela, il y aura un débordement de pile et l'erreur suivante sera renvoyée:
RangeError: taille maximale de la pile d'appels dépassée
Avec le script ci-dessous (basé sur cet article de blog ), en rattrapant cette erreur, vous pouvez calculer la limite pour votre environnement spécifique.
Avertissement! L'exécution de ce script prend du temps et, selon les performances de votre système, peut ralentir ou bloquer votre navigateur/système!
let testArray = Array.from({length: 10000}, () => Math.floor(Math.random() * 2000000));
for (i = 10000; i < 1000000; ++i) {
testArray.Push(Math.floor(Math.random() * 2000000));
try {
Math.max.apply(null, testArray);
} catch (e) {
console.log(i);
break;
}
}
Basé sur le test dans le commentaire de EscapeNetscape , j’ai créé des points de repère qui testent 5 méthodes différentes sur un tableau contenant uniquement 100 000 éléments aléatoires .
En 2019, les résultats montrent que la boucle standard (dont BTW n'a pas la taille limite) est la plus rapide du monde. apply
et spread vient juste après, puis beaucoup plus tard, la solution hybride de MDN puis reduce
est la plus lente.
Presque tous les tests ont donné les mêmes résultats, à l'exception d'un qui s'est avéré le plus lent.
Si vous augmentez votre tableau pour avoir 1 million d’éléments, les choses commencent à casser et vous restez avec la boucle standard en solution rapide et reduce
en ralentissement.
var testArrayLength = 100000
var testArray = Array.from({length: testArrayLength}, () => Math.floor(Math.random() * 2000000));
// ES6 spread
Math.min(...testArray);
Math.max(...testArray);
// reduce
testArray.reduce(function(a, b) {
return Math.max(a, b);
});
testArray.reduce(function(a, b) {
return Math.min(a, b);
});
// apply
Math.min.apply(Math, testArray);
Math.max.apply(Math, testArray);
// standard loop
let max = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
if (testArray[i] > max) {
max = testArray[i];
}
}
let min = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
if (testArray[i] < min) {
min = testArray[i];
}
}
// MDN hibrid soltuion
// Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#Using_apply_and_built-in_functions
function minOfArray(arr) {
var min = Infinity;
var QUANTUM = 32768;
for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
min = Math.min(submin, min);
}
return min;
}
minOfArray(testArray);
function maxOfArray(arr) {
var max = -Infinity;
var QUANTUM = 32768;
for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
var submax = Math.max.apply(null, arr.slice(i, Math.max(i + QUANTUM, len)));
max = Math.max(submax, max);
}
return max;
}
maxOfArray(testArray);
Si vous êtes paranoïaque comme moi à propos de l'utilisation de Math.max.apply
(ce qui pourrait provoquer des erreurs lorsque de grands tableaux selon MDN ), essayez ceci:
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);
});
}
Ou, dans 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));
}
Les fonctions anonymes sont malheureusement nécessaires (au lieu d'utiliser Math.max.bind(Math)
parce que reduce
ne passe pas seulement a
et b
à sa fonction, mais aussi i
et un référence au tableau lui-même, nous devons donc nous assurer que nous n'essayons pas d'appeler max
également.
.apply
est souvent utilisé lorsque l'intention est d'invoquer une fonction variadique avec une liste de valeurs d'arguments, par exemple.
La fonction Math.max([value1[,value2, ...]])
renvoie le plus grand des zéro ou plus chiffres.
Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20
La méthode Math.max()
ne vous permet pas de passer un tableau. Si vous avez une liste de valeurs dont vous devez obtenir la plus grande, vous devez normalement appeler cette fonction à l'aide de Function.prototype.apply () , par exemple.
Math.max.apply(null, [10, 20]); // 20
Math.max.apply(null, [-10, -20]); // -10
Math.max.apply(null, [-10, 20]); // 20
Cependant, à partir de ECMAScript 6 , vous pouvez utiliser le opérateur de propagation :
L'opérateur spread permet de développer une expression à des endroits où plusieurs arguments (pour les appels de fonction) ou plusieurs éléments (pour les littéraux de tableau) sont attendus.
En utilisant l'opérateur spread, ce qui précède peut être réécrit de la manière suivante:
Math.max(...[10, 20]); // 20
Math.max(...[-10, -20]); // -10
Math.max(...[-10, 20]); // 20
Lorsque vous appelez une fonction à l'aide de l'opérateur variadic, vous pouvez même ajouter des valeurs supplémentaires, par ex.
Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50
Bonus:
L'opérateur Spread vous permet d'utiliser la syntaxe littérale de tableau pour créer de nouveaux tableaux lorsque, dans ES5, vous devez revenir au code impératif, en utilisant une combinaison de Push
, splice
, etc., etc.
let foo = ['b', 'c'];
let bar = ['a', ...foo, 'd', 'e']; // ['a', 'b', 'c', 'd', 'e']
Vous le faites en étendant le type Array:
Array.max = function( array ){
return Math.max.apply( Math, array );
};
Array.min = function( array ){
return Math.min.apply( Math, array );
};
Renforcé à partir de ici (par John Resig)
Une solution simple pour trouver la valeur minimale sur une Array
d'éléments consiste à utiliser la fonction prototype Array
reduce
:
A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min ? val : min, A[0]); // returns -9
ou en utilisant la fonction intégrée Math.Min () de JavaScript (merci @Tenflex):
A.reduce((min,val) => Math.min(min,val), A[0]);
Cela règle min
sur A[0]
, puis vérifie si A[1]...A[n]
s’il est strictement inférieur à la valeur actuelle min
. Si A[i] < min
, alors min
est mis à jour pour A[i]
. Lorsque tous les éléments du tableau ont été traités, min
est renvoyé comme résultat.
Deux manières sont plus courtes et faciles:
let arr = [2, 6, 1, 0]
// Way 1:
let max = Math.max.apply(null, arr)
//Way 2:
let max = arr.reduce(function(a, b) {
return Math.max(a, b);
});
Une autre façon de le faire:
var arrayMax = Function.prototype.apply.bind(Math.max, null);
Usage:
var max = arrayMax([2, 5, 1]);
D'autres ont déjà donné des solutions dans lesquelles ils augmentent Array.prototype
. Tout ce que je veux dans cette réponse est de préciser s'il doit s'agir de Math.min.apply( Math, array )
ou Math.min.apply( null, array )
. Alors quel contexte doit être utilisé, Math
ou null
?
Lorsque vous passez null
en tant que contexte à apply
, le contexte sera par défaut défini sur l'objet global (l'objet window
dans le cas des navigateurs). Passer l'objet Math
comme contexte serait la bonne solution, mais passer à null
ne vous fera pas de mal. Voici un exemple où null
pourrait causer des problèmes lors de la décoration de la fonction Math.max
:
// 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);
Ce qui précède lève une exception car this.foo
sera évalué comme window.foo
, ce qui correspond à undefined
. Si nous remplaçons null
par Math
, les choses fonctionneront comme prévu et la chaîne "foo" sera imprimée à l'écran (je l'ai testé avec Mozilla Rhino ).
Vous pouvez presque en déduire que personne n’a décoré Math.max
donc passer null
fonctionnera sans problème.
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/max
function getMaxOfArray(numArray) {
return Math.max.apply(null, numArray);
}
var arr = [100, 0, 50];
console.log(getMaxOfArray(arr))
cela a fonctionné pour moi.
Je suis surpris de ne pas mentionner la fonction de réduction.
var arr = [1, 10, 5, 11, 2]
var b = arr.reduce(function(previous,current){
return previous > current ? previous:current
});
b => 11
arr => [1, 10, 5, 11, 2]
Cela peut convenir à vos objectifs.
Array.prototype.min = function(comparer) {
if (this.length === 0) return null;
if (this.length === 1) return this[0];
comparer = (comparer || Math.min);
var v = this[0];
for (var i = 1; i < this.length; i++) {
v = comparer(this[i], v);
}
return v;
}
Array.prototype.max = function(comparer) {
if (this.length === 0) return null;
if (this.length === 1) return this[0];
comparer = (comparer || Math.max);
var v = this[0];
for (var i = 1; i < this.length; i++) {
v = comparer(this[i], v);
}
return v;
}
Pour les tableaux de grande taille (~ 10⁷ éléments), Math.min
et Math.max
produisent une erreur RangeError (taille maximale de la pile d'appels dépassée) dans node.js.
Pour les grands tableaux, une solution rapide et sale est la suivante:
Array.prototype.min = function() {
var r = this[0];
this.forEach(function(v,i,a){if (v<r) r=v;});
return r;
};
J'ai eu le même problème, j'avais besoin d'obtenir les valeurs minimales et maximales d'un tableau et, à ma grande surprise, il n'y avait pas de fonctions intégrées pour les tableaux. Après avoir beaucoup lu, j'ai décidé de tester moi-même le "top 3" des solutions:
Le code de test était le suivant:
function GetMaxDISCRETE(A)
{ var MaxX=A[0];
for (var X=0;X<A.length;X++)
if (MaxX<A[X])
MaxX=A[X];
return MaxX;
}
function GetMaxAPPLY(A)
{ return Math.max.apply(null,A);
}
function GetMaxREDUCE(A)
{ return A.reduce(function(p,c)
{ return p>c?p:c;
});
}
Le tableau A était rempli de 100 000 nombres entiers aléatoires, chaque fonction étant exécutée 10 000 fois sur Mozilla Firefox 28.0 sur un poste de travail Intel Pentium 4 2.99 GHz avec Windows Vista. Les temps sont en secondes, récupérés par la fonction performance.now (). Les résultats sont les suivants, avec 3 chiffres fractionnaires et écart type:
La solution REDUCE était 117% plus lente que la solution discrète. La solution APPLY était la pire, 2118% plus lente que la solution discrète. En outre, comme Peter l'a fait remarquer, cela ne fonctionne pas pour les grands tableaux (plus de 1 000 000 d'éléments).
Aussi, pour compléter les tests, j'ai testé ce code discret étendu:
var MaxX=A[0],MinX=A[0];
for (var X=0;X<A.length;X++)
{ if (MaxX<A[X])
MaxX=A[X];
if (MinX>A[X])
MinX=A[X];
}
Le timing: moyenne = 0.218s, SD = 0.094
Elle est donc 35% plus lente que la solution discrète simple, mais elle récupère simultanément les valeurs maximale et minimale (toute autre solution prendrait au moins le double de celle nécessaire pour les récupérer). Une fois que le PO a besoin des deux valeurs, la solution discrète serait le meilleur choix (même si deux fonctions distinctes, une pour calculer le maximum et une autre pour calculer le minimum, seraient supérieures à la deuxième meilleure solution, la solution REDUCE).
Vous pouvez utiliser la fonction suivante n'importe où dans votre projet:
function getMin(array){
return Math.min.apply(Math,array);
}
function getMax(array){
return Math.max.apply(Math,array);
}
Et ensuite, vous pouvez appeler les fonctions qui passent le tableau:
var myArray = [1,2,3,4,5,6,7];
var maximo = getMax(myArray); //return the highest number
Le code suivant fonctionne pour moi:
var valueList = [10,4,17,9,3];
var maxValue = valueList.reduce(function(a, b) { return Math.max(a, b); });
var minValue = valueList.reduce(function(a, b) { return Math.min(a, b); });
Les Math.min
et Math.max
sont tous deux des opérations récursives dont le plus probable est crach pour les grands tableaux (plus de ~ 10⁷ éléments).
Au lieu de cela, vous pouvez utiliser les anciennes boucles javascript comme ceci:
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] });
}
Ou (meilleur temps d'exécution) :
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 };
}
* Testé avec 1 000 000 d'articles:
Juste pour référence, le temps d’exécution de la première fonction (sur ma machine) était de 15,84 ms par rapport à la 2e fonction avec seulement 4,32 ms.
Parcourez, gardez la trace au fur et à mesure.
var min = null;
var max = null;
for (var i = 0, len = arr.length; i < len; ++i)
{
var elem = arr[i];
if (min === null || min > elem) min = elem;
if (max === null || max < elem) max = elem;
}
alert( "min = " + min + ", max = " + max );
Cela laissera min/max null s'il n'y a pas d'éléments dans le tableau. Définira min et max en un seul passage si le tableau contient des éléments.
Vous pouvez également étendre Array avec une méthode range
en utilisant ce qui précède pour permettre la réutilisation et l’amélioration de la lisibilité. Voir un violon en marche à http://jsfiddle.net/9C9fU/
Array.prototype.range = function() {
var min = null,
max = null,
i, len;
for (i = 0, len = this.length; i < len; ++i)
{
var elem = this[i];
if (min === null || min > elem) min = elem;
if (max === null || max < elem) max = elem;
}
return { min: min, max: max }
};
Utilisé comme
var arr = [3, 9, 22, -7, 44, 18, 7, 9, 15];
var range = arr.range();
console.log(range.min);
console.log(range.max);
Je pensais partager ma solution simple et facile à comprendre.
Pour le min:
var arr = [3, 4, 12, 1, 0, 5];
var min = arr[0];
for (var k = 1; k < arr.length; k++) {
if (arr[k] < min) {
min = arr[k];
}
}
console.log("Min is: " + min);
Et pour le max:
var arr = [3, 4, 12, 1, 0, 5];
var max = arr[0];
for (var k = 1; k < arr.length; k++) {
if (arr[k] > max) {
max = arr[k];
}
}
console.log("Max is: " + max);
Des choses simples, vraiment.
var arr = [10,20,30,40];
arr.max = function() { return Math.max.apply(Math, this); }; //attach max funct
arr.min = function() { return Math.min.apply(Math, this); }; //attach min funct
alert("min: " + arr.min() + " max: " + arr.max());
Utiliser Math.max()
ou Math.min()
Math.max(10, 20); // 20
Math.min(-10, -20); // -20
La fonction suivante utilise Function.prototype.apply()
pour rechercher le maximum d'éléments dans un tableau numérique. getMaxOfArray([1, 2, 3])
est équivalent à Math.max(1, 2, 3)
, mais vous pouvez utiliser getMaxOfArray()
sur des tableaux construits par programme de toute taille.
function getMaxOfArray(numArray) {
return Math.max.apply(null, numArray);
}
Ou avec le nouvel opérateur de propagation, obtenir le maximum d'un tableau devient beaucoup plus facile.
var arr = [1, 2, 3];
var max = Math.max(...arr); // 3
var min = Math.min(...arr); // 1
Voici un moyen d'obtenir la valeur maximale d'un tableau d'objets. Créez une copie (avec tranche), puis triez la copie par ordre décroissant et récupérez le premier élément.
var myArray = [
{"ID": 1, "Cost": 200},
{"ID": 2, "Cost": 1000},
{"ID": 3, "Cost": 50},
{"ID": 4, "Cost": 500}
]
maxsort = myArray.slice(0).sort(function(a, b) { return b.ID - a.ID })[0].ID;
La solution de ChaosPandion fonctionne si vous utilisez un prototype. Si non, considérez ceci:
Array.max = function( array ){
return Math.max.apply( Math, array );
};
Array.min = function( array ){
return Math.min.apply( Math, array );
};
Ce qui précède renvoie NaN si une valeur de tableau n'est pas un entier, vous devez donc créer certaines fonctionnalités pour éviter cela. Sinon, cela fonctionnera.
Essayer
let max= a=> a.reduce((m,x)=> m>x ? m:x);
let min= a=> a.reduce((m,x)=> m<x ? m:x);
let max= a=> a.reduce((m,x)=> m>x ? m:x);
let min= a=> a.reduce((m,x)=> m<x ? m:x);
// TEST - pixel buffer
let arr = Array(200*800*4).fill(0);
arr.forEach((x,i)=> arr[i]=100-i%101);
console.log('Max', max(arr));
console.log('Min', min(arr))
Pour Math.min/max (+ apply), nous obtenons une erreur:
Taille maximale de la pile d'appels dépassée (Chrome 74.0.3729.131)
// TEST - pixel buffer
let arr = Array(200*800*4).fill(0);
arr.forEach((x,i)=> arr[i]=100-i%101);
let max1= Math.max(...arr); // Maximum call stack size exceeded
let max2= Math.max.apply(null, arr); // Maximum call stack size exceeded
// same for min
let arr = [2,5,3,5,6,7,1];
let max = Math.max(...arr); // 7
let min = Math.min(...arr); // 1
Si vous utilisez le framework prototype.js , alors ce code fonctionnera correctement:
arr.min();
arr.max();
Documenté ici: prototype de framework Javascript pour max
Si vous utilisez la bibliothèque sugar.js , vous pouvez écrire arr.min () et arr.max () comme vous suggérer. Vous pouvez également obtenir des valeurs min et max à partir de tableaux non numériques.
min (map, all = false) Renvoie l'élément du tableau avec la valeur la plus basse. map peut être une fonction mappant la valeur à vérifier ou une chaîne faisant office de raccourci. Si tout est vrai, toutes les valeurs minimales d'un tableau seront retournées.
max (map, all = false) Renvoie l'élément du tableau avec la plus grande valeur. map peut être une fonction mappant la valeur à vérifier ou une chaîne faisant office de raccourci. Si tout est vrai, toutes les valeurs maximales dans un tableau seront retournées.
Exemples:
[1,2,3].min() == 1
['fee','fo','fum'].min('length') == "fo"
['fee','fo','fum'].min('length', true) == ["fo"]
['fee','fo','fum'].min(function(n) { return n.length; }); == "fo"
[{a:3,a:2}].min(function(n) { return n['a']; }) == {"a":2}
['fee','fo','fum'].max('length', true) == ["fee","fum"]
Bibliothèques comme Lo-Dash et underscore.js fournit également de puissantes fonctions min et max similaires:
Exemple de Lo-Dash:
_.max([4, 2, 8, 6]) == 8
var characters = [
{ 'name': 'barney', 'age': 36 },
{ 'name': 'fred', 'age': 40 }
];
_.max(characters, function(chr) { return chr.age; }) == { 'name': 'fred', 'age': 40 }
minHeight = Math.min.apply({},YourArray);
minKey = getCertainKey(YourArray,minHeight);
maxHeight = Math.max.apply({},YourArray);
maxKey = getCertainKey(YourArray,minHeight);
function getCertainKey(array,certainValue){
for(var key in array){
if (array[key]==certainValue)
return key;
}
}
Après avoir lu toutes les réponses, j’ai pensé qu’il serait bien d’écrire la solution la plus solide (qui n’a pas été fournie ici) que j’ai rencontrée. Si votre tableau de valeurs peut atteindre plusieurs dizaines de milliers, utilisez une stratégie hybride: appliquez votre fonction à des fragments du tableau à la fois:
function minOfArray(arr) {
var min = Infinity;
var QUANTUM = 32768;
for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
var submin = Math.min.apply(null,
arr.slice(i, Math.min(i+QUANTUM, len)));
min = Math.min(submin, min);
}
return min;
}
var min = minOfArray([5, 6, 2, 3, 7]);
Source: MDN
créer un objet simple
var myArray = new Array();
myArray = [10,12,14,100];
var getMaxHeight = {
hight : function( array ){ return Math.max.apply( Math, array );
}
getMaxHeight.hight(myArray);
Le script ci-dessous a fonctionné pour moi dans ndoejs:
var numbers = [1, 2, 3, 4];
console.log('Value:: ' + Math.max.apply(null, numbers) ); // 4
J'aime l'approche de réduction () de Linus , en particulier pour les tableaux de grande taille. Mais aussi longtemps que vous savez que vous avez besoin de min et de max, pourquoi parcourir le tableau deux fois?
Array.prototype.minmax = function () {
return this.reduce(function (p, v) {
return [(p[0] < v ? p[0] : v), (p[1] > v ? p[1] : v)];
}, [this[0], this[0]]);
}
Bien sûr, si vous préférez l'approche itérative, vous pouvez également le faire:
Array.prototype.minmax = function () {
var mn = this[0], mx = this[0];
this.forEach(function (v) {
if (v < mn) mn = v;
if (v > mx) mx = v;
});
return [mn, mx];
};
Insérez les numéros séparés par une virgule et cliquez sur l'événement que vous souhaitez appeler, par exemple, Obtenir le numéro maximum ou minimum.
function maximumNumber() {
var numberValue = document.myForm.number.value.split(",");
var numberArray = [];
for (var i = 0, len = numberValue.length; i < len; i += 1) {
numberArray.Push(+numberValue[i]);
var largestNumber = numberArray.reduce(function (x, y) {
return (x > y) ? x : y;
});
}
document.getElementById("numberOutput").value = largestNumber;
}
function minimumNumber() {
var numberValue = document.myForm.number.value.split(",");
var numberArray = [];
for (var i = 0, len = numberValue.length; i < len; i += 1) {
numberArray.Push(+numberValue[i]);
var smallestNumber = numberArray.reduce(function (x, y) {
return (x < y) ? x : y;
});
}
document.getElementById("numberOutput").value = smallestNumber;
}
function restrictCharacters(evt) {
evt = (evt) ? evt : window.event;
var charCode = (evt.which) ? evt.which : evt.keyCode;
if (((charCode >= '48') && (charCode <= '57')) || (charCode == '44')) {
return true;
}
else {
return false;
}
}
<div>
<form name="myForm">
<table>
<tr>
<td>Insert Number</td>
<td><input type="text" name="number" id="number" onkeypress="return restrictCharacters(event);" /></td>
<td><input type="button" value="Maximum" onclick="maximumNumber();" /></td>
<td><input type="button" value="Minimum" onclick="minimumNumber();"/></td>
<td><input type="text" id="numberOutput" name="numberOutput" /></td>
</tr>
</table>
</form>
</div>
si vous avez un objet complexe, vous pouvez utiliser le type .... tel que: si je veux un objet qui contient la valeur MAX/MIN ci-dessous objs.
var objs= [
{name:"Apple",value:3},
{name:"Love",value:32},
{name:"Cheese",value:1},
{name:"Pork",value:77},
{name:"Xmas",value:99}
];
Je vais faire une sorte:
objs.sort(function(a, b){return a.value-b.value});
Alors: objs[0]
est le MIN, objs[objs.length-1]
est le MAX.
Voici un autre exemple. Calculez la valeur Max/Min d'un tableau avec lodash.
let array = [100, 0, 50];
var func = _.over(Math.max, Math.min);
var [max, min] = func(...array);
// => [100, 0]
console.log(max);
console.log(min);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Pour éviter que "max" et "min" soient répertoriés dans une boucle "for ... in":
Object.defineProperty(Array.prototype, "max", {
enumerable: false,
configurable: false,
writable: false,
value: function() {
return Math.max.apply(null, this);
}
});
Object.defineProperty(Array.prototype, "min", {
enumerable: false,
configurable: false,
writable: false,
value: function() {
return Math.min.apply(null, this);
}
});
tilisation:
var x = [10,23,44,21,5];
x.max(); //44
x.min(); //5
Il se peut que vous ne souhaitiez pas ajouter de méthodes au prototype Array, ce qui pourrait entrer en conflit avec d'autres bibliothèques.
J'ai vu beaucoup d'exemples utiliser forEach, ce que je ne recommanderais pas pour les grands tableaux en raison de ses performances médiocres par rapport à une boucle for. https://coderwall.com/p/kvzbpa/don-t-use-array-foreach-use-for-instead
Aussi Math.max(Math, [1,2,3]);
me donne toujours NaN?
function minArray(a) {
var min=a[0]; for(var i=0,j=a.length;i<j;i++){min=a[i]<min?a[i]:min;}
return min;
}
function maxArray(a) {
var max=a[0]; for(var i=0,j=a.length;i<j;i++){max=a[i]>max?a[i]:max;}
return max;
}
minArray([1,2,3]); // returns 1
Si vous avez un tableau d'objets, l'exemple de fonction minArray () ci-dessous accepte 2 paramètres, le premier est le tableau et le second est le nom de clé de la valeur de la clé à comparer. La fonction dans ce cas renverrait l'index du tableau qui a la plus petite valeur de clé donnée.
function minArray(a, key) {
var min, i, j, index=0;
if(!key) {
min=a[0];
for(i=0,j=a.length;i<j;i++){min=a[i]<min?a[i]:min;}
return min;
}
min=a[0][key];
for(i=0,j=a.length;i<j;i++){
if(a[i][key]<min) {
min = a[i][key];
index = i;
}
}
return index;
}
var a = [{fee: 9}, {fee: 2}, {fee: 5}];
minArray(a, "fee"); // returns 1, as 1 is the proper array index for the 2nd array element.
approche linéaire, presque purement fonctionnelle
var min=[0, 29, 25].map((function(max) {max=-Infinity; return function(e) {return max=Math.max(max, e);}})())[0]
Plus d'exemples:
Savoir min valeur
function getMin(arr) {
return (ar || [0, 29, 25]).
map((function(max) {max=-Infinity; return function(e) {return max=Math.max(max, e);}})())[0];
}
ou en utilisant la méthode Array.map
avec fermeture variable
function getMin(arrObjs) {
return (arrObjs || [{val: 0}, {val: 29}, {val: 25}]).
map((function(max) {max=-Infinity; return function(e) {return max=(max.val>e.val?max:e);}})())[0];
}
Savoir max valeur
function getMax(arr) {
return (ar || [0, 29, 25]).
map((function(v) {v=Infinity; return function(e) {return v=Math.min(v, e);}})())[0];
}
pour tableau d'objets
function getMax(arrObjs) {
return (arrObjs || [{val: 0}, {val: 29}, {val: 25}]).
map((function(v) {v=-Infinity; return function(e) {return v=(v.val<e.val?v:e);}})())[0];
}
Vous pouvez utiliser Array.sort mais vous devrez écrire une fonction de tri de nombre simple car la valeur par défaut est alphabétique.
Ensuite, vous pouvez saisir arr[0]
et arr[arr.length-1]
pour obtenir les valeurs min et max.
Si vous avez besoin de performances, c’est le meilleur moyen pour les petits tableaux:
var min = 99999;
var max = 0;
for(var i = 0; i < v.length; i++)
{
if(v[i] < min)
{
min = v[i];
}
if(v[i] >= max)
{
max = v[i];
}
}