Comment puis-je facilement obtenir l'élément min ou max d'un tableau JavaScript?
Exemple de pseudo-code:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
javascript
HankH
la source
la source
...
) avecMath.max()
comme ceci:Math.max(...[2, 5, 16, 1])
. Voir ma réponse faite à partir de la documentation MDN .Math.max.apply(null, [2,5,16,1])
Réponses:
Que diriez-vous d'augmenter l'objet Array intégré pour utiliser
Math.max
/ à laMath.min
place:Voici un JSFiddle .
Augmenter les Encastrements peut provoquer des collisions avec d' autres bibliothèques (certains voient), donc vous pouvez être plus à l' aise avec juste
apply
« ingMath.xxx()
à votre tableau directement:Alternativement, en supposant que votre navigateur prend en charge ECMAScript 6, vous pouvez utiliser l' opérateur d'étalement qui fonctionne de manière similaire à la
apply
méthode:la source
null
ouMath
ou{}
ou quoi que ce soit àapply()
oucall()
n'a aucune incidence sur le résultat.Math.max
ne fait ni ne doit faire référence enthis
interne.Math.max.apply(null, $.makeArray(array));
.max
ou.min
à l'avenir. Scénario parfaitement réaliste: vous utilisez cette réponse. En 2016, spécification ES7 ou ES8Array.max
etArray.min
. Contrairement à cette version, ils fonctionnent sur des chaînes. Votre futur collègue essaie d'obtenir la dernière chaîne alphabétique dans un tableau avec la.max()
méthode native désormais bien documentée , mais l'obtient mystérieusementNaN
. Quelques heures plus tard, elle trouve ce code, exécute ungit blame
et maudit votre nom.Pour une discussion complète, voir: http://aaroncrane.co.uk/2008/11/javascript_max_api/
la source
Math.max.apply(Math, array)
etMath.max.apply(null, array)
? Le blog dit "... vous devez également redire redondamment quimax
appartient àMath
...", mais il semble que je ne doive pas le faire (en définissant le premier argument deapply
asnull
).Math.max(a,b)
,Math
est passé en tant quethis
valeur, il peut donc être judicieux de faire de même lors de l'appel avecapply
. MaisMath.max
n'utilise pas lathis
valeur, vous pouvez donc transmettre la valeur que vous souhaitez.Pour les grands tableaux (~ 10⁷ éléments),
Math.min
et lesMath.max
deux produisent l'erreur suivante dans Node.js.Une solution plus robuste consiste à ne pas ajouter tous les éléments à la pile d'appels, mais à passer à la place un tableau:
Si vous êtes préoccupé par la vitesse, le code suivant est environ 3 fois plus rapide que
Math.max.apply
sur mon ordinateur. Voir http://jsperf.com/min-and-max-in-array/2 .Si vos tableaux contiennent des chaînes au lieu de nombres, vous devez également les contraindre en nombres. Le code ci-dessous fait cela, mais il ralentit le code ~ 10 fois sur ma machine. Voir http://jsperf.com/min-and-max-in-array/3 .
la source
min
etmax
au dernier élément et réduire les itérations de 1 (while(--len)
);)very different results
vous l'avez fait 5 ans plus tard)reduce
solution est la plus lente. Même si vous travaillez avec un tableau contenant des millions d'éléments, il est préférable d'utiliser la norme for loop . Voir ma réponse pour en savoir plus.Utilisation de l'opérateur d'étalement (ES6)
Afficher l'extrait de code
la source
If no arguments are given, the result is -∞.
tl; dr
Solution MDN
La documentation officielle de MDN sur
Math.max()
couvre déjà ce problème:Taille maximale d'un tableau
Selon MDN, les
apply
solutions et spread avaient une limitation de 65536 qui provenait de la limite du nombre maximum d'arguments:Ils fournissent même une solution hybride qui n'a pas vraiment de bonnes performances par rapport à d'autres solutions. Voir test de performance ci-dessous pour en savoir plus.
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 étalé, la taille maximale des tableaux uniquement numériques est d'environ 120000 . Au-dessus de cela, il y aura un débordement de pile et l'erreur suivante sera levée:Avec le script ci-dessous (basé sur cet article de blog ), en détectant cette erreur, vous pouvez calculer la limite de votre environnement spécifique.
Attention! L'exécution de ce script prend du temps et selon les performances de votre système, il peut ralentir ou planter votre navigateur / système!
Performances sur de grandes baies
Sur la base du test dans le commentaire d' EscapeNetscape , j'ai créé des repères qui testent 5 méthodes différentes sur un tableau de nombres aléatoires uniquement avec 100 000 éléments .
En 2019, les résultats montrent que la boucle standard (dont BTW n'a pas la limitation de taille) est la plus rapide partout.
apply
et la propagation suit de près, puis beaucoup plus tard la solution hybride de MDN, puisreduce
la plus lente.Presque tous les tests ont donné les mêmes résultats, sauf un où la propagation s'est avérée être la plus lente.
Si vous augmentez votre tableau pour avoir 1 million d'articles, les choses commencent à se casser et vous vous retrouvez avec la boucle standard comme solution rapide et
reduce
plus lente.Référence JSPerf
Référence JSBen
Référence JSBench.me
Code source de référence
Afficher l'extrait de code
la source
Math.max.apply(Math, arr)
une compatibilité «max».(...)
etapply
échouent ou renvoient le mauvais résultat si le tableau contient trop d'éléments [...] La solution de réduction n'a pas ce problème" En testant Chrome, FF, Edge et IE11, il semble que ce soit le cas ok pour un tableau de jusqu'à 100k valeurs. (Testé sur Win10 et les derniers navigateurs: Chrome 110k, Firefox 300k, Edge 400k, IE11 150k).Si vous êtes paranoïaque comme moi à propos de l'utilisation
Math.max.apply
(ce qui pourrait provoquer des erreurs lors de la fourniture de grands tableaux selon MDN ), essayez ceci:Ou, dans ES6:
Les fonctions anonymes sont malheureusement nécessaires (au lieu d'utiliser
Math.max.bind(Math)
parcereduce
que ne passe pas seulementa
etb
à sa fonction, mais aussii
et une référence au tableau lui-même, nous devons donc nous assurer que nous n'essayons pas de les appelermax
également.la source
Math.max(...array)
?apply
, et a donc les mêmes inconvénients (limite d'argument maximale).function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
Math.min()
sans valeur, renvoieInfinity
, donc ces fonctions pourraient utiliserreduce(..., Infinity)
pour correspondre à ce comportement. Je préfère cependant qu'il lance une exception (comme il le fait actuellement), car prendre le minimum d'un tableau vide semble être une erreur..apply
est souvent utilisé lorsque l'intention est d'invoquer une fonction variadique avec une liste de valeurs d'argument, par exempleLa
Math.max([value1[,value2, ...]])
fonction renvoie le plus grand de zéro ou plusieurs nombres.La
Math.max()
méthode ne vous permet pas de passer dans un tableau. Si vous avez une liste de valeurs dont vous avez besoin pour obtenir la plus grande, vous appelez normalement cette fonction en utilisant Function.prototype.apply () , par exempleCependant, à partir de l' ECMAScript 6, vous pouvez utiliser l' opérateur d'étalement :
En utilisant l'opérateur d'étalement, les éléments ci-dessus peuvent être réécrits comme tels:
Lors de l'appel d'une fonction à l'aide de l'opérateur variadic, vous pouvez même ajouter des valeurs supplémentaires, par exemple
Prime:
Opérateur de propagation vous permet d'utiliser le tableau syntaxe littérale pour créer de nouveaux tableaux dans des situations où ES5 vous auriez besoin de revenir à un code impératif, en utilisant une combinaison de
push
,splice
etc.la source
concat
de la plupart des programmeurs car il vous permet de conserver un style de ligne unique.Deux façons sont plus courtes et faciles:
Voie 1 :
Voie 2 :
la source
0
vous pouvez utiliser[0].concat(arr)
ou avec une syntaxe étendue[0, ...arr]
(à la place de 'arr')Pour ce faire, étendez le type de tableau:
Boosté d' ici (par John Resig)
la source
Une solution simple pour trouver la valeur minimale sur un
Array
des éléments est d'utiliser laArray
fonction prototypereduce
:ou en utilisant la fonction Math.Min () intégrée de JavaScript (merci @Tenflex):
Cette valeur est définie
min
surA[0]
, puis vérifieA[1]...A[n]
si elle est strictement inférieure à la valeur actuellemin
. SiA[i] < min
alorsmin
est mis à jour versA[i]
. Lorsque tous les éléments du tableau ont été traités,min
est renvoyé comme résultat.EDIT : Inclure la position de la valeur minimale:
la source
min
valeur retournée mais aussi sa position dans le tableau?D'autres ont déjà donné quelques solutions dans lesquelles ils augmentent
Array.prototype
. Tout ce que je veux dans cette réponse est de clarifier si cela devrait êtreMath.min.apply( Math, array )
ouMath.min.apply( null, array )
. Alors, quel contexte devrait être utilisé,Math
ounull
?Lors du passage en
null
tant que contexte àapply
, le contexte sera par défaut l'objet global (l'window
objet dans le cas des navigateurs). Passer l'Math
objet en tant que contexte serait la bonne solution, mais cela ne fera pas de mal nonnull
plus. Voici un exemple oùnull
pourrait causer des problèmes, lors de la décoration de laMath.max
fonction:Ce qui précède lèvera une exception car
this.foo
sera évalué commewindow.foo
, ce qui estundefined
. Si nous remplaçonsnull
parMath
, les choses fonctionneront comme prévu et la chaîne "foo" sera imprimée à l'écran (j'ai testé cela en utilisant Mozilla Rhino ).Vous pouvez à peu près supposer que personne n'a décoré
Math.max
ainsi, le passagenull
fonctionnera sans problème.la source
Foo.staticMethod
et ferait-il référencethis
? Ne serait-ce pas une erreur dans la conception du décorateur? (à moins bien sûr qu'ils voulaient faire référence à la portée globale et qu'ils souhaitent rester indépendants du moteur JavaScript utilisé, par exemple Rhino).Math.max
, implémenté par spécification, n'utilise pasthis
. Si quelqu'un remplaceMath.max
tel qu'il l'utilisethis
, alors il a rendu son comportement contraire aux spécifications et vous devez lui lancer des objets pointus. Vous ne devriez pas coder autour de cette possibilité pas plus que vous ne coderiez autour de la possibilité que quelqu'un ait troquéMath.max
etMath.min
pour le lulz.Une autre façon de le faire:
Usage:
la source
Méthodes alternatives
Les
Math.min
etMath.max
méthodes sont les deux opérations récursives qui sont ajoutés à la pile d'appel de moteur JS, et le plus probable accident pour un tableau qui contient un grand nombre d'articles(plus de ~ 10⁷ articles, dépend du navigateur de l'utilisateur).
Utilisez plutôt quelque chose comme ceci:
Ou avec un meilleur temps d'exécution:
Ou pour obtenir à la fois Min et Max:
Ou avec un temps d'exécution encore meilleur *:
* Testé avec 1000000 articles:
Juste pour référence, le temps d'exécution de la 1ère fonction (sur ma machine) était de 15,84 ms par rapport à la 2e fonction avec seulement 4,32 ms.
la source
Cela peut convenir à vos besoins.
la source
comparer
censé être appelé dans une portée spécifique? Parce que c'est comme çathis[index]
qui fait référence àundefined
chaque fois.Math.xxx
) fonctionnera dans la portée globale ...https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/max
cela a fonctionné pour moi.
la source
Je suis surpris que personne n'ait mentionné la fonction de réduction.
la source
Pour les grands tableaux (~ 10⁷ éléments),
Math.min
etMath.max
génère une 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 source
J'ai eu le même problème, j'avais besoin d'obtenir les valeurs minimum et maximum 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 les solutions "top 3":
Le code de test était le suivant:
Le tableau A était rempli de 100 000 nombres entiers aléatoires, chaque fonction a été exécutée 10 000 fois sur Mozilla Firefox 28.0 sur un bureau 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 étaient les suivants, avec 3 chiffres fractionnaires et l'écart type:
La solution REDUCE était 117% plus lente que la solution discrète. La solution APPLY était la pire, 2 118% plus lente que la solution discrète. En outre, comme Peter l'a observé, cela ne fonctionne pas pour les grands tableaux (environ plus de 1 000 000 d'éléments).
Aussi, pour terminer les tests, j'ai testé ce code discret étendu:
Le timing: moyenne = 0,218 s, sd = 0,094
Ainsi, elle est 35% plus lente que la solution discrète simple, mais elle récupère à la fois les valeurs maximale et minimale à la fois (toute autre solution prendrait au moins deux fois celle pour les récupérer). Une fois que l'OP avait besoin des deux valeurs, la solution discrète serait le meilleur choix (même si deux fonctions distinctes, une pour le calcul du maximum et une autre pour le calcul du minimum, elles surperformaient la deuxième meilleure, la solution REDUCE).
la source
Vous pouvez utiliser la fonction suivante n'importe où dans votre projet:
Et puis vous pouvez appeler les fonctions passant le tableau:
la source
Le code suivant fonctionne pour moi:
la source
Parcourez, gardez une trace au fur et à mesure.
Cela laissera min / max null s'il n'y a aucun élément dans le tableau. Fixera min et max en une seule passe si le tableau a des éléments.
Vous pouvez également étendre Array avec une
range
méthode utilisant ce qui précède pour permettre la réutilisation et améliorer la lisibilité. Voir un violon fonctionnel sur http://jsfiddle.net/9C9fU/Utilisé comme
la source
range
fonction qui serait le meilleur moyen d'obtenir à la fois le min et le max à la fois IMO - comme je l'ai fait avec une mise à jour de ma réponse.J'ai pensé partager ma solution simple et facile à comprendre.
Pour le min:
Et pour le max:
la source
for…in
énumérations sur les tableaux!Des trucs simples, vraiment.
la source
Voici une façon d'obtenir la valeur maximale d'un tableau d'objets. Créez une copie (avec tranche), puis triez la copie dans l'ordre décroissant et récupérez le premier élément.
la source
Utilisation de
Math.max()
ouMath.min()
La fonction suivante utilise
Function.prototype.apply()
pour rechercher l'élément maximum dans un tableau numérique.getMaxOfArray([1, 2, 3])
est équivalent àMath.max(1, 2, 3)
, mais vous pouvez l'utilisergetMaxOfArray()
sur des tableaux construits par programmation de n'importe quelle taille.Ou avec le nouvel opérateur d'étalement, obtenir le maximum d'un tableau devient beaucoup plus facile.
la source
Outre l'utilisation des fonctions mathématiques max et min, une autre fonction à utiliser est la fonction intégrée de sort (): c'est parti
la source
La solution de ChaosPandion fonctionne si vous utilisez protoype. Sinon, considérez ceci:
Ce qui précède renverra NaN si une valeur de tableau n'est pas un entier, vous devez donc créer des fonctionnalités pour éviter cela. Sinon, cela fonctionnera.
la source
Math
objet comme contexte?Si vous utilisez la bibliothèque sugar.js , vous pouvez écrire arr.min () et arr.max () comme vous le suggérez. Vous pouvez également obtenir des valeurs min et max à partir de tableaux non numériques.
Exemples:
Des bibliothèques comme Lo-Dash et underscore.js fournissent également des fonctions min et max puissantes similaires:
Exemple de Lo-Dash:
la source
la source
Essayer
Afficher l'extrait de code
Pour Math.min / max (+ appliquer), nous obtenons une erreur:
Afficher l'extrait de code
la source