Pregunta Encuentra el elemento min / max de una matriz en JavaScript


¿Cómo puedo obtener fácilmente el elemento mínimo o máximo de una matriz de JavaScript?

Ejemplo Psuedocode:

let array = [100, 0, 50]

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

578
2017-11-03 18:18


origen


Respuestas:


¿Qué hay de aumentar el objeto Array incorporado para usar Math.max/Math.min en lugar:

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

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

Aquí hay un JSFiddle.

Aumentar los built-ins puede causar colisiones con otras bibliotecas (algunos lo ven), por lo que puede sentirse más cómodo con solo apply'En g Math.xxx() a su matriz directamente:

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

Alternativamente, suponiendo que su navegador sea compatible con ECMAScript 6, puede usar operador de propagación que funciona de manera similar a la apply método:

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

682
2017-11-03 18:23



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

Para una discusión completa, vea: http://aaroncrane.co.uk/2008/11/javascript_max_api/


308
2018-05-23 20:01



Para arreglos grandes (~ 10⁷ elementos), Math.min y Math.max ambos producen el siguiente error en Node.js.

RangeError: se ha excedido el tamaño máximo de la pila de llamadas

Una solución más robusta es no agregar cada elemento a la pila de llamadas, sino pasar una matriz:

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 le preocupa la velocidad, el siguiente código es ~ 3 veces más rápido que Math.max.apply está en mi computadora. Ver 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 sus matrices contienen cadenas en lugar de números, también debe forzarlos a formar números. El siguiente código hace eso, pero ralentiza el código ~ 10 veces en mi máquina. Ver 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



Usar el operador de difusión (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 eres paranoico como yo acerca de usar Math.max.apply (lo que podría causar errores cuando se le den matrices grandes) de acuerdo con MDN), prueba esto:

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

O, 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));
}

Las funciones anónimas son desafortunadamente necesarias (en lugar de usar Math.max.bind(Math) porque reduce no solo pasa a y b a su función, pero también i y una referencia a la matriz en sí, así que tenemos que asegurarnos de que no intentemos llamar max en esos también.


51
2017-07-27 01:00



tl; dr

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

Oficial Math.max() Documentación de MDN

La siguiente función usa Function.prototype.apply () para encontrar el elemento máximo en una matriz numérica. getMaxOfArray([1, 2, 3]) es equivalente a Math.max(1, 2, 3), pero puedes usar getMaxOfArray() en matrices construidas mediante programación de cualquier tamaño.

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

O con el nuevo operador de propagación, obtener el máximo de una matriz se vuelve mucho más fácil.

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

46
2018-06-14 21:22



.apply a menudo se usa cuando la intención es invocar una función variadica con una lista de valores de argumento, p.

los Math.max([value1[,value2, ...]]) la función devuelve el mayor de cero o más números.

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

los Math.max() método no le permite pasar una matriz. Si tiene una lista de valores de los cuales necesita obtener la más grande, normalmente llamaría a esta función usando Function.prototype.apply (), p.ej.

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

Sin embargo, a partir de ECMAScript 6 puedes usar el operador de propagación:

El operador de difusión permite que una expresión se expanda en lugares donde se esperan múltiples argumentos (para llamadas a funciones) o múltiples elementos (para literales de matriz).

Usando el operador de propagación, lo anterior se puede reescribir como tal:

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

Cuando se llama a una función utilizando el operador variadic, incluso se pueden agregar valores adicionales, p.

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

Prima:

El operador de extensión le permite usar la sintaxis literal de la matriz para crear nuevas matrices en situaciones en las que en ES5 deberá recurrir al código imperativo, utilizando una combinación 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



Lo haces extendiendo el tipo de matriz:

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

Impulsado desde aquí (por John Resig)


21
2017-11-03 18:35



Otros ya han dado algunas soluciones en las que aumentan Array.prototype. Todo lo que quiero en esta respuesta es aclarar si debería ser Math.min.apply( Math, array ) o Math.min.apply( null, array ). Entonces, ¿qué contexto debería usarse? Math o null? 

Al pasar null como contexto para apply, entonces el contexto se predeterminará al objeto global (el window objeto en el caso de los navegadores). Pasando el Math objetar ya que el contexto sería la solución correcta, pero no pasará nada null ya sea. Aquí hay un ejemplo cuando null podría causar problemas, al decorar el Math.max función:

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

Lo anterior arrojará una excepción porque this.foo será evaluado como window.foo, cual es undefined. Si reemplazamos null con Math, las cosas funcionarán como se espera y la cadena "foo" se imprimirá en la pantalla (probé esto usando Mozilla Rhino)

Puedes asumir que nadie ha decorado Math.max entonces, pasando null funcionará sin problemas


15
2017-11-03 18:39



Una forma más de hacerlo:

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

Uso:

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

14
2017-09-26 18:43