Eu tenho um object JavaScript Array simples contendo alguns números.
[267, 306, 108]
Existe uma function que encontre o maior número nessa matriz?
Resig ao resgate:
Array.max = function( array ){ return Math.max.apply( Math, array ); };
Você pode usar a function apply, para chamar Math.max :
var array = [267, 306, 108]; var largest = Math.max.apply(Math, array); // 306
Como funciona?
A function apply é usada para chamar outra function, com um determinado contexto e argumentos, fornecidos como uma matriz. As funções min e max podem receber um número arbitrário de argumentos de input: Math.max (val1, val2, …, valN)
Então, se nós chamamos:
Math.min.apply(Math, [1,2,3,4]);
A function apply será executada:
Math.min(1,2,3,4);
Observe que o primeiro parâmetro, o contexto, não é importante para essas funções, pois elas são estáticas, elas funcionarão independentemente do que é transmitido como contexto.
Descobri que, para matrizes maiores (~ elementos de 100k), vale a pena simplesmente iterar a matriz com um laço de execução modesto, com desempenho 30% melhor do que Math.max.apply()
:
function mymax(a) { var m = -Infinity, i = 0, n = a.length; for (; i != n; ++i) { if (a[i] > m) { m = a[i]; } } return m; }
Resultados de referência
A syntax mais fácil, com o novo operador de spread :
var arr = [1, 2, 3]; var max = Math.max(...arr);
Fonte: Mozilla MDN
Eu não sou especialista JS, mas eu queria ver como esses methods se comparam, então isso foi uma boa prática para mim. Eu não sei se isso é tecnicamente o caminho certo para testar esses testes, mas eu os corri um após o outro, como você pode ver no meu código.
Classificar e obter o 0º valor é de longe o pior método (e modifica a ordem da sua matriz, o que pode não ser desejável). Para os outros, a diferença é insignificante, a menos que você esteja falando de milhões de índices.
Resultados médios de cinco execuções com uma matriz de números randoms de 100.000 índices:
var performance = window.performance function findmax(array) { var max = 0, a = array.length, counter for (counter=0;counter max) { max = array[counter] } } return max } function findBiggestNumber(num) { var counts = [] var i for (i = 0; i < num; i++) { counts.push(Math.random()) } var a, b a = performance.now() var biggest = counts.reduce(function(highest, count){ return highest > count ? highest : count }, 0) b = performance.now() console.log('reduce took ' + (b - a) + ' ms to run') a = performance.now() var biggest2 = Math.max.apply(Math, counts) b = performance.now() console.log('Math.max.apply took ' + (b - a) + ' ms to run') a = performance.now() var biggest3 = counts.sort(function(a,b){return ba;})[0] b = performance.now() console.log('sorting and getting the 0th value took ' + (b - a) + ' ms to run') a = performance.now() var biggest4 = counts.reduce(function(highest, count){ return Math.max(highest,count) }, 0) b = performance.now() console.log('Math.max within reduce() took ' + (b - a) + ' ms to run') a = performance.now() var biggest5 = findmax(counts) b = performance.now() console.log('custom findmax function took ' + (b - a) + ' ms to run') console.log(biggest + '-' + biggest2 + '-' + biggest3 + '-' + biggest4 + '-' + biggest5) } findBiggestNumber(1E5)
Você pode classificar a matriz em ordem decrescente e obter o primeiro item:
[267, 306, 108].sort(function(a,b){return ba;})[0]
Que tal agora:
var arr = [1,2,3,4]; var largest = arr.reduce(function(x,y){ return (x > y) ? x : y; }); console.log(largest);
que tal usar Array.reduce ?
[0,1,2,3,4].reduce(function(previousValue, currentValue){ return Math.max(previousValue,currentValue); });
Encontrar max e min valoriza o caminho fácil e manual. Este código é muito mais rápido que o Math.max.apply
; Eu tentei até 1000k números em matriz.
function findmax(array) { var max = 0; var a = array.length; for (counter=0;counter max) { max = array[counter]; } } return max; } function findmin(array) { var min = array[0]; var a = array.length; for (counter=0;counter
Quase todas as respostas usam Math.max.apply()
que é bom e elegante, mas tem limitações.
Argumentos de function são colocados na pilha que tem uma desvantagem – um limite. Portanto, se sua matriz for maior que o limite, ela falhará com RangeError: Maximum call stack size exceeded.
Para encontrar um tamanho de pilha de chamadas, usei este código:
var ar = []; for (var i = 1; i < 100*99999; i++) { ar.push(1); try { var max = Math.max.apply(Math, ar); } catch(e) { console.log('Limit reached: '+i+' error is: '+e); break; } }
Provou ser o maior em FireFox na minha máquina - 591519 . Isso significa que, se a matriz contiver mais de 591519 itens, Math.max.apply()
resultará em RangeError .
A melhor solução para este problema é a maneira iterativa (crédito: https://developer.mozilla.org/ ):
max = -Infinity, min = +Infinity; for (var i = 0; i < numbers.length; i++) { if (numbers[i] > max) max = numbers[i]; if (numbers[i] < min) min = numbers[i]; }
Eu escrevi sobre esta questão no meu blog aqui .
https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Math/max
const inputArray = [ 1, 3, 4, 9, 16, 2, 20, 18]; const maxNumber = Math.max(...inputArray); console.log(maxNumber);
Sim, claro que existem: Math.max.apply(null,[23,45,67,-45])
e o resultado retorna 67
;
Não esqueça que o wrap pode ser feito com Function.prototype.bind
, dando a você uma function “all-native”.
var aMax = Math.max.apply.bind(Math.max, Math); aMax([1, 2, 3, 4, 5]); // 5
Você também pode estender o Array
para ter essa function e torná-la parte de todo array.
Array.prototype.max = function(){return Math.max.apply( Math, this )}; myArray = [1,2,3]; console.log( myArray.max() );
var max = []; for(var i=0; arr.length>i; i++ ){ var arra = arr[i]; var largest = Math.max.apply(Math, arra); max.push(largest); } return max;
Você também pode usar paraEach :
var maximum = Number.MIN_SAFE_INTEGER; var array = [-3, -2, 217, 9, -8, 46]; array.forEach(function(value){ if(value > maximum) { maximum = value; } }); console.log(maximum); // 217
Usando – Array.prototype.reduce()
é legal!
[267, 306, 108].reduce((acc,val)=> (acc>val)?acc:val)
onde acc = accumulator e val = valor atual ;
var a = [267, 306, 108].reduce((acc,val)=> (acc>val)?acc:val); console.log(a);
Você pode tentar isso
var arr = [267,306,108]; var largestNum = 0; for(i=0;ilargest){ var largest = arr[i]; } } console.log(largest);
Acabei de começar com JS, mas acho que esse método seria bom:
var array = [34, 23, 57, 983, 198];
var score = 0; for(var i = 0; i = array.length; i++) { if(array[ i ] > score) { score = array[i]; } }
Rode isto:
Array.prototype.max = function(){ return Math.max.apply( Math, this ); };
E agora tente [3,10,2].max()
retorna 10
Encontre o valor Max e Min usando o Bubble Sort
var arr = [267, 306, 108]; for(i=0, k=0; iarr[j]) { k = arr[i]; arr[i] = arr[j]; arr[j] = k; } } } console.log('largest Number: '+ arr[0]); console.log('Smallest Number: '+ arr[arr.length-1]);