¿Cómo puedo obtener fácilmente el elemento min o max de una matriz de JavaScript?
Psuedocódigo de ejemplo:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
javascript
HankH
fuente
fuente

...) conMath.max()la siguiente manera:Math.max(...[2, 5, 16, 1]). Vea mi respuesta hecha de la documentación de MDN .Math.max.apply(null, [2,5,16,1])Respuestas:
¿Qué tal aumentar el objeto Array incorporado para usar
Math.max/ en suMath.minlugar:Aquí hay un JSFiddle .
Aumentar los muebles empotrados puede causar colisiones con otras bibliotecas (algunos ven), por lo que puede ser más cómodo con sólo
apply'ingMath.xxx()a la matriz directamente:Alternativamente, suponiendo que su navegador sea compatible con ECMAScript 6, puede usar el operador de propagación que funciona de manera similar al
applymétodo:fuente
nulloMatho{}lo que seaapply()ocall()no tiene relación con el resultado.Math.maxno hace ni debe hacer referenciathisinternamente.Math.max.apply(null, $.makeArray(array));.maxo un.minmétodo en el futuro. Escenario perfectamente realista: utiliza esta respuesta. En 2016, las especificaciones ES7 o ES8Array.maxyArray.min. A diferencia de esta versión, trabajan en cadenas. Su futuro colega intenta obtener la secuencia alfabéticamente más reciente en una matriz con el.max()método nativo ahora bien documentado , pero lo consigue misteriosamenteNaN. Horas después, encuentra este código, ejecuta ungit blamey maldice su nombre.Para una discusión completa ver: http://aaroncrane.co.uk/2008/11/javascript_max_api/
fuente
Math.max.apply(Math, array)yMath.max.apply(null, array)? El blog dice "... también tienes que repetir de forma redundante quemaxpertenece aMath...", pero parece que no tengo que hacerlo (estableciendo el primer argumento deapplyasnull).Math.max(a,b),Mathse pasa como elthisvalor, por lo que puede tener sentido hacer lo mismo al llamar conapply. PeroMath.maxno utiliza elthisvalor, por lo que puede pasar el valor que desee.Para grandes matrices (~ 10⁷ elementos),
Math.minyMath.maxambas producen el siguiente error en Node.js.Una solución más robusta es no agregar todos los elementos a la pila de llamadas, sino pasar una matriz:
Si le preocupa la velocidad, el siguiente código es ~ 3 veces más rápido
Math.max.applyque en mi computadora. Ver http://jsperf.com/min-and-max-in-array/2 .Si sus matrices contienen cadenas en lugar de números, también debe convertirlas en 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 .
fuente
minymaxal último elemento y reducir las iteraciones en 1 (while(--len));)very different resultslo hiciste 5 años después)reducesolución es la más lenta. Incluso si trabaja con una matriz que tiene millones de elementos, es mejor usar el estándar for loop . Vea mi respuesta para más.Uso del operador de propagación (ES6)
Mostrar fragmento de código
fuente
If no arguments are given, the result is -∞.tl; dr
Solución MDN
Los documentos oficiales de MDN
Math.max()ya cubren este tema:Tamaño máximo de una matriz
De acuerdo con MDN, las
applysoluciones extendidas tenían una limitación de 65536 que provenía del límite del número máximo de argumentos:Incluso proporcionan una solución híbrida que realmente no tiene un buen rendimiento en comparación con otras soluciones. Consulte la prueba de rendimiento a continuación para obtener más información.
En 2019, el límite real es el tamaño máximo de la pila de llamadas . Para los navegadores de escritorio modernos basados en Chromium, esto significa que cuando se trata de encontrar min / max con
applyo spread, prácticamente el tamaño máximo para matrices de números solamente es ~ 120000 . Por encima de esto, habrá un desbordamiento de pila y se lanzará el siguiente error:Con el siguiente script (basado en esta publicación de blog ), al detectar ese error puede calcular el límite para su entorno específico.
¡Advertencia! ¡Ejecutar este script lleva tiempo y, dependiendo del rendimiento de su sistema, puede ralentizar o bloquear su navegador / sistema!
Rendimiento en matrices grandes
Basado en la prueba en el comentario de EscapeNetscape , creé algunos puntos de referencia que prueban 5 métodos diferentes en una matriz de solo números aleatorios con 100000 elementos .
En 2019, los resultados muestran que el bucle estándar (que por cierto no tiene la limitación de tamaño) es el más rápido en todas partes.
applyy la propagación viene de cerca, luego mucho más tarde la solución híbrida de MDN y luegoreducecomo la más lenta.Casi todas las pruebas dieron los mismos resultados, excepto una en la que la propagación resultó ser la más lenta.
Si intensifica su matriz para tener 1 millón de elementos, las cosas comienzan a romperse y queda con el bucle estándar como una solución rápida y
reducemás lenta.Punto de referencia JSPerf
Punto de referencia JSBen
Punto de referencia JSBench.me
Código fuente de referencia
Mostrar fragmento de código
fuente
Math.max.apply(Math, arr)para una compatibilidad 'máxima'.(...)yapplyfallarán o devolverán el resultado incorrecto si la matriz tiene demasiados elementos [...] La solución de reducción no tiene este problema" Al probar Chrome, FF, Edge e IE11 parece que es ok para una matriz de hasta 100k valores. (Probado en Win10 y los últimos navegadores: Chrome 110k, Firefox 300k, Edge 400k, IE11 150k).Si eres paranoico como yo sobre el uso
Math.max.apply(lo que podría causar errores cuando se le dan matrices grandes de acuerdo con MDN ), intente esto:O, en ES6:
Desafortunadamente, las funciones anónimas son necesarias (en lugar de usar
Math.max.bind(Math)porquereduceno solo pasanayba su función, sino tambiéniy una referencia a la matriz en sí, por lo que debemos asegurarnos de no tratar de invocarlasmaxtambién.fuente
Math.max(...array)?apply, por lo tanto, tiene los mismos inconvenientes (límite máximo de argumentos).function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }Math.min()sin valores, devuelveInfinity, por lo que estas funciones podrían usarsereduce(..., Infinity)para coincidir con ese comportamiento. Sin embargo, prefiero que arroje una excepción (como lo hace actualmente), porque tomar el mínimo de una matriz vacía parece ser un error..applya menudo se usa cuando la intención es invocar una función variadic con una lista de valores de argumentos, por ej.La
Math.max([value1[,value2, ...]])función devuelve el mayor de cero o más números.El
Math.max()método no le permite pasar en una matriz. Si tiene una lista de valores de los cuales necesita obtener el mayor, normalmente llamaría a esta función usando Function.prototype.apply () , por ejemploSin embargo, a partir del ECMAScript 6 puede usar el operador de propagación :
Usando el operador de propagación, lo anterior puede reescribirse como tal:
Al llamar a una función utilizando el operador variable, incluso puede agregar valores adicionales, por ejemplo
Prima:
Operador de difusión le permite utilizar la sintaxis literal de matriz para crear nuevas matrices en situaciones donde en la ES5 que tendría que recurrir al código imperativo, utilizando una combinación de
push,splice, etc.fuente
concatmayoría de los programadores escribirán su último ejemplo en la bonificación porque le permite mantener un estilo de línea única.Dos formas son más cortas y fáciles:
Camino 1 :
Camino 2 :
fuente
0, puede usar[0].concat(arr)o con sintaxis extendida[0, ...arr](en lugar de 'arr')Lo haces extendiendo el tipo de matriz:
Impulsado desde aquí (por John Resig)
fuente
Una solución simple para encontrar el valor mínimo sobre uno
Arrayde los elementos es usar laArrayfunción prototiporeduce:o usando la función incorporada Math.Min () de JavaScript (gracias @Tenflex):
Esto se establece
minenA[0], y luego verificaA[1]...A[n]si es estrictamente menor que el actualmin. SiA[i] < minluegominse actualiza aA[i]. Cuando se han procesado todos los elementos de la matriz,minse devuelve como resultado.EDITAR : Incluir posición de valor mínimo:
fuente
minvalor devuelto sino también su posición en la matriz?Otros ya han dado algunas soluciones en las que aumentan
Array.prototype. Todo lo que quiero en esta respuesta es aclarar si debería serMath.min.apply( Math, array )oMath.min.apply( null, array ). Entonces, ¿qué contexto se debe utilizarMathonull?Al pasar
nullcomo contexto aapply, el contexto se convertirá por defecto en el objeto global (elwindowobjeto en el caso de los navegadores). Pasar elMathobjeto como contexto sería la solución correcta, pero tampoco le hará daño pasarnull. Aquí hay un ejemplo de cuándonullpodría causar problemas al decorar laMath.maxfunción:Lo anterior arrojará una excepción porque
this.foose evaluará comowindow.foo, que esundefined. Si reemplazamosnullconMath, las cosas funcionarán como se esperaba y la cadena "foo" se imprimirá en la pantalla (probé esto usando Mozilla Rhino ).Se puede suponer que nadie lo ha decorado
Math.max, así que pasarnullfuncionará sin problemas.fuente
Foo.staticMethody haría referenciathis? ¿No sería eso un error en el diseño del decorador? (a menos que, por supuesto, quisieran hacer referencia al alcance global y quieran permanecer independientes del motor de JavaScript que se utiliza, por ejemplo, Rhino).Math.max, implementado por especificación, no utilizathis. Si alguien anula deMath.maxtal manera que sí lo usathis, entonces ha hecho que su comportamiento viole las especificaciones y usted debe arrojarles objetos afilados. No debe codificar alrededor de esa posibilidad más de lo que codificaría alrededor de la posibilidad de que alguien haya cambiadoMath.maxyMath.minpor el lulz.Una forma más de hacerlo:
Uso:
fuente
Metodos alternativos
Los métodos
Math.minyMath.maxson operaciones recursivas que se agregan a la pila de llamadas del motor JS, y muy probablemente se bloquean para una matriz que contiene una gran cantidad de elementos(más de ~ 10⁷ elementos, depende del navegador del usuario).
En cambio, use algo como esto:
O con mejor tiempo de ejecución:
O para obtener Min y Max:
O con un tiempo de ejecución aún mejor *:
* Probado con 1,000,000 de elementos:
solo como referencia, el tiempo de ejecución de la primera función (en mi máquina) fue de 15.84 ms frente a la segunda función con solo 4.32 ms.
fuente
Esto puede adaptarse a sus propósitos.
fuente
comparersupone que debe llamarse en algún ámbito específico? Porque como se hace referenciathis[index]que esundefinedcada vez.Math.xxx) se ejecuta en el ámbito global ...https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/max
Esto funcionó para mí.
fuente
Me sorprende que nadie haya mencionado la función de reducción.
fuente
Para grandes matrices (~ 10⁷ elementos),
Math.minyMath.maxobtiene un RangeError (Tamaño máximo de la pila de llamadas excedido) en node.js.Para matrices grandes, una solución rápida y sucia es:
fuente
Tuve el mismo problema, necesitaba obtener los valores mínimos y máximos de una matriz y, para mi sorpresa, no había funciones integradas para las matrices. Después de leer mucho, decidí probar yo mismo las "3 mejores soluciones":
El código de prueba fue este:
La matriz A se llenó con 100,000 números enteros aleatorios, cada función se ejecutó 10,000 veces en Mozilla Firefox 28.0 en un escritorio Intel Pentium 4 a 2.99GHz con Windows Vista. Los tiempos están en segundos, recuperados por la función performance.now (). Los resultados fueron estos, con 3 dígitos fraccionarios y desviación estándar:
La solución REDUCE fue un 117% más lenta que la solución discreta. La solución APLICAR fue la peor, 2,118% más lenta que la solución discreta. Además, como observó Peter, no funciona para matrices grandes (más de 1,000,000 de elementos).
Además, para completar las pruebas, probé este código discreto extendido:
El tiempo: media = 0.218s, sd = 0.094
Por lo tanto, es un 35% más lento que la solución discreta simple, pero recupera los valores máximos y mínimos al mismo tiempo (cualquier otra solución tomaría al menos el doble para recuperarlos). Una vez que el OP necesitara ambos valores, la solución discreta sería la mejor opción (incluso si dos funciones separadas, una para calcular el máximo y otra para calcular el mínimo, superarían a la segunda mejor, la solución REDUCIR).
fuente
Puede usar la siguiente función en cualquier parte de su proyecto:
Y luego puede llamar a las funciones que pasan la matriz:
fuente
El siguiente código funciona para mí:
fuente
Iterar a través, manteniendo un registro sobre la marcha.
Esto dejará min / max nulo si no hay elementos en la matriz. Establecerá min y max en una pasada si la matriz tiene algún elemento.
También puede extender Array con un
rangemétodo que utiliza lo anterior para permitir la reutilización y mejorar la legibilidad. Vea un violín de trabajo en http://jsfiddle.net/9C9fU/Usado como
fuente
rangefunción que sería la mejor manera de obtener el mínimo y el máximo al mismo tiempo IMO, como lo hice con una actualización de mi respuesta.Pensé en compartir mi solución simple y fácil de entender.
Para el min:
Y para el máximo:
fuente
for…inenumeraciones en matrices!Cosas simples, de verdad.
fuente
Aquí hay una forma de obtener el valor máximo de una matriz de objetos. Cree una copia (con corte), luego ordene la copia en orden descendente y tome el primer elemento.
fuente
Usando
Math.max()oMath.min()La siguiente función se utiliza
Function.prototype.apply()para encontrar el elemento máximo en una matriz numérica.getMaxOfArray([1, 2, 3])es equivalente aMath.max(1, 2, 3), pero puede usarlogetMaxOfArray()en matrices construidas mediante programación de cualquier tamaño.O con el nuevo operador de propagación, obtener el máximo de una matriz se vuelve mucho más fácil.
fuente
Además de usar la función matemática max y min, otra función a usar es la función incorporada de sort (): aquí vamos
fuente
La solución de ChaosPandion funciona si está utilizando un prototipo. Si no, considere esto:
Lo anterior devolverá NaN si un valor de matriz no es un entero, por lo que debe crear alguna funcionalidad para evitar eso. De lo contrario, esto funcionará.
fuente
Mathobjeto como contexto?Si usa la biblioteca sugar.js , puede escribir arr.min () y arr.max () como sugiere. También puede obtener valores mínimos y máximos de matrices no numéricas.
Ejemplos:
Bibliotecas como Lo-Dash y underscore.js también proporcionan funciones mínimas y máximas potentes similares:
Ejemplo de Lo-Dash:
fuente
fuente
Tratar
Mostrar fragmento de código
Para Math.min / max (+ apply) obtenemos el error:
Mostrar fragmento de código
fuente