web-dev-qa-db-fra.com

Trouver l'élément min / max d'un tableau en JavaScript

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
683
HankH

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 );
_
757
Roatin Marth
var max_of_array = Math.max.apply(Math, array);

Pour une discussion complète, voir: http://aaroncrane.co.uk/2008/11/javascript_max_api/

342
newspire

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;
};
175
Linus Unnebäck

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)
)
138
Abdennour TOUMI

tl; dr

// 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];
  }
}

Solution MDN

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 utiliser getMaxOfArray() 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);

Taille maximale d'un tableau

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;
  }
}

Performance sur les grands tableaux

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.

référence JSPerf

jsperf.com benchmark results for different solutions to find the min/max item of an array

référence JSBen

jsben.com benchmark results for different solutions to find the min/max item of an array

référence JSBench.me

jsbench.me benchmark results for different solutions to find the min/max item of an array

Code source de référence

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);
85
totymedli

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.

64
Daniel Buckmaster

.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']
38
Gajus

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)

22
inkedmn

Une solution simple pour trouver la valeur minimale sur une Array d'éléments consiste à utiliser la fonction prototype Arrayreduce:

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.

20

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);
});
18
Hafizur Rahman

Une autre façon de le faire:

var arrayMax = Function.prototype.apply.bind(Math.max, null);

Usage:

var max = arrayMax([2, 5, 1]);
15
sbr

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.

15
Ionuț G. Stan

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.

13
Fuad Ibrahimov

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]
12
Stallion_V

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;
}
10
ChaosPandion

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;
};
9
Peter

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:

  1. solution discrète: une boucle FOR pour vérifier chaque élément du tableau par rapport à la valeur maximale et/ou minimale actuelle;
  2. Solution APPLY: envoi du tableau aux fonctions internes de Math.max et/ou Math.min à l'aide de apply (null, array);
  3. Solution REDUCE: récurrence d'une vérification sur chaque élément du tableau en utilisant une réduction (fonction).

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:

  1. Solution discrète: moyenne = 0,161 s, écart type = 0,078
  2. APPLIQUER solution: moyenne = 3,571 s, écart type = 0,487
  3. REDUIRE solution: moyenne = 0,350 s, écart type = 0,044

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).

8
Cyberknight

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
8
Max Cabrera

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); });
8
jaydip jadhav

Math.min & Math.max

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.

7
Lior Elrom

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);
6
tvanfosson

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);
6
Ionut

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());
5
Brian

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
5
shilovk

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; 
5
Ben

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.

4
jay

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
3
let arr = [2,5,3,5,6,7,1];

let max = Math.max(...arr); // 7
let min = Math.min(...arr); // 1
3
Chawki

Si vous utilisez le framework prototype.js , alors ce code fonctionnera correctement:

arr.min();
arr.max();

Documenté ici: prototype de framework Javascript pour max

3
Prcela

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 }
3
andersh
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;
   }
} 
2
stevenlee

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

2
Humoyun Ahmad

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);
1
Yene Mulatu

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
1
Rahul Mankar

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];
};
1
fearless_fool

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>
0
Mayur Narula

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.

0
Vin.X

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>
0
Penny Liu

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
0
lepe

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.
0
micahblu

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];
}
0
test30

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.

Regardez l'exemple 2 ici.

Ensuite, vous pouvez saisir arr[0] et arr[arr.length-1] pour obtenir les valeurs min et max.

0
Pablo

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];
    }
}
0
Kamil