Question 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 de code d'article:

let array = [100, 0, 50]

array.min() //=> 0
array.max() //=> 100

578
2017-11-03 18:18


origine


Réponses:


Que diriez-vous d'augmenter l'objet Array intégré à utiliser Math.max/Math.min au lieu:

Array.prototype.max = function() {
  return Math.max.apply(null, this);
};

Array.prototype.min = function() {
  return Math.min.apply(null, this);
};

Voici une JSFiddle.

Augmenter les built-ins peut provoquer des collisions avec d'autres bibliothèques (certaines voient), donc vous serez peut-être plus à l'aise avec juste apply'ing Math.xxx() à votre tableau directement:

var min = Math.min.apply(null, arr),
    max = Math.max.apply(null, arr);

Alternativement, en supposant que votre navigateur supporte ECMAScript 6, vous pouvez utiliser le opérateur de propagation qui fonctionne de la même manière que le apply méthode:

var min = Math.min( ...arr ),
    max = Math.max( ...arr );

682
2017-11-03 18:23



var max_of_array = Math.max.apply(Math, array);

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


308
2018-05-23 20:01



Pour les grands tableaux (~ 10⁷ éléments), Math.min et Math.max Les deux produisent 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 tous les éléments à la pile d'appels, mais à passer à la place 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 ~ 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 chiffres, 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.

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

141
2017-11-18 14:00



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


88
2017-08-23 16:37



Si vous êtes paranoïaque comme moi à propos de l'utilisation Math.max.apply (ce qui pourrait causer des erreurs lors de l'administration de grands tableaux selon MDN), essaye ça:

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, en 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) car reduce ne passe pas seulement a et b à sa fonction, mais aussi i et une référence à la matrice elle-même, nous devons donc nous assurer que nous n'essayons pas d'appeler max sur ceux aussi bien.


51
2017-07-27 01:00



tl; dr

var max = Math.max(...arrayOfNumbers);

Officiel Math.max() Documentation MDN

La fonction suivante utilise Function.prototype.apply () pour trouver l'élément maximum 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 n'importe quelle taille.

function getMaxOfArray(numArray) {
    return Math.max.apply(null, numArray);
}

Ou avec la nouvelle opérateur de propagation, obtenir le maximum d'un tableau devient beaucoup plus facile.

var arr = [1, 2, 3];
var max = Math.max(...arr);

46
2018-06-14 21:22



.apply est souvent utilisé lorsque l'intention est d'invoquer une fonction variadique avec une liste de valeurs d'arguments, par ex.

le Math.max([value1[,value2, ...]]) La fonction renvoie le plus grand des nombres zéro ou plus.

Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20

le Math.max() La méthode ne vous permet pas de passer dans un tableau. Si vous avez une liste de valeurs dont vous avez besoin pour obtenir le plus grand, vous appelez normalement cette fonction en utilisant 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 du ECMAScript 6 vous pouvez utiliser le opérateur de propagation:

L'opérateur spread permet d'étendre une expression dans 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, les éléments ci-dessus peuvent être réécrits en tant que tels:

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 variadique, vous pouvez même ajouter des valeurs supplémentaires, par ex.

Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50

Prime:

L'opérateur Spread vous permet d'utiliser la syntaxe littérale de tableau pour créer de nouveaux tableaux dans les situations où, dans ES5, vous devez revenir au code impératif, en utilisant une combinaison de push, splice, etc.

let foo = ['b', 'c'];
let bar = ['a', ...foo, 'd', 'e']; // ['a', 'b', 'c', 'd', 'e']

34
2017-12-18 01:38



Vous le faites en étendant le type de tableau:

Array.max = function( array ){
    return Math.max.apply( Math, array );
};
Array.min = function( array ){
    return Math.min.apply( Math, array );
}; 

Boosté de ici (par John Resig)


21
2017-11-03 18:35



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 clarifier si cela devrait être Math.min.apply( Math, array ) ou Math.min.apply( null, array ). Alors quel contexte devrait être utilisé, Math ou null? 

En passant null comme contexte à apply, le contexte sera par défaut à l'objet global (le window objet dans le cas des navigateurs). Passer le Math objet que le contexte serait la bonne solution, mais il ne nuira pas à passer null non plus. Voici un exemple quand null pourrait causer des problèmes, lors de la décoration du Math.max fonction:

// 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 va jeter une exception parce que this.foo sera évalué comme window.foo, lequel est undefined. Si nous remplaçons null avec Math, les choses vont fonctionner comme prévu et la chaîne "foo" sera imprimée à l'écran (je l'ai testé en utilisant Mozilla Rhino).

Vous pouvez à peu près supposer que personne n'a décoré Math.max donc, en passant null fonctionnera sans problèmes.


15
2017-11-03 18:39



Une autre façon de le faire:

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

Usage:

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

14
2017-09-26 18:43