// 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];
}
}
The official MDN docs on Math.max()
already covers this issue:
The following function uses Function.prototype.apply() to find the maximum element in a numeric array.
getMaxOfArray([1, 2, 3])
is equivalent toMath.max(1, 2, 3)
, but you can usegetMaxOfArray()
on programmatically constructed arrays of any size.function getMaxOfArray(numArray) { return Math.max.apply(null, numArray); }
Or with the new spread operator, getting the maximum of an array becomes a lot easier.
var arr = [1, 2, 3]; var max = Math.max(...arr);
According to MDN the apply
and spread solutions had a limitation of 65536 that came from the limit of the maximum number of arguments:
But beware: in using apply this way, you run the risk of exceeding the JavaScript engine's argument length limit. The consequences of applying a function with too many arguments (think more than tens of thousands of arguments) vary across engines (JavaScriptCore has hard-coded argument limit of 65536), because the limit (indeed even the nature of any excessively-large-stack behavior) is unspecified. Some engines will throw an exception. More perniciously, others will arbitrarily limit the number of arguments actually passed to the applied function. To illustrate this latter case: if such an engine had a limit of four arguments (actual limits are of course significantly higher), it would be as if the arguments 5, 6, 2, 3 had been passed to apply in the examples above, rather than the full array.
They even provide a hybrid solution which doesn't really have good performance compared to other solutions. See performance test below for more.
In 2019 the actual limit is the maximum size of the call stack. For modern Chromium based desktop browsers this means that when it comes to finding min/max with apply
or spread, practically the maximum size for numbers only arrays is ~120000. Above this, there will be a stack overflow and the following error will be thrown:
RangeError: Maximum call stack size exceeded
With the script below (based on this blog post), by catching that error you can calculate the limit for your specific environment.
Warning! Running this script takes time and depending on the performance of your system it might slow or crash your browser/system!
let testArray = Array.from({length: 10000}, () => Math.floor(Math.random() * 2000000));_x000D_
for (i = 10000; i < 1000000; ++i) {_x000D_
testArray.push(Math.floor(Math.random() * 2000000));_x000D_
try {_x000D_
Math.max.apply(null, testArray);_x000D_
} catch (e) {_x000D_
console.log(i);_x000D_
break;_x000D_
}_x000D_
}
_x000D_
Based on the test in EscapeNetscape's comment I created some benchmarks that tests 5 different methods on a random number only array with 100000 items.
In 2019, the results show that the standard loop (which BTW doesn't have the size limitation) is the fastest everywhere. apply
and spread comes closely after it, then much later MDN's hybrid solution then reduce
as the slowest.
Almost all tests gave the same results, except for one where spread somewhy ended up being the slowest.
If you step up your array to have 1 million items, things start to break and you are left with the standard loop as a fast solution and reduce
as a slower.
var testArrayLength = 100000_x000D_
var testArray = Array.from({length: testArrayLength}, () => Math.floor(Math.random() * 2000000));_x000D_
_x000D_
// ES6 spread_x000D_
Math.min(...testArray);_x000D_
Math.max(...testArray);_x000D_
_x000D_
// reduce_x000D_
testArray.reduce(function(a, b) {_x000D_
return Math.max(a, b);_x000D_
});_x000D_
testArray.reduce(function(a, b) {_x000D_
return Math.min(a, b);_x000D_
});_x000D_
_x000D_
// apply_x000D_
Math.min.apply(Math, testArray);_x000D_
Math.max.apply(Math, testArray);_x000D_
_x000D_
// standard loop_x000D_
let max = testArray[0];_x000D_
for (let i = 1; i < testArrayLength; ++i) {_x000D_
if (testArray[i] > max) {_x000D_
max = testArray[i];_x000D_
}_x000D_
}_x000D_
_x000D_
let min = testArray[0];_x000D_
for (let i = 1; i < testArrayLength; ++i) {_x000D_
if (testArray[i] < min) {_x000D_
min = testArray[i];_x000D_
}_x000D_
}_x000D_
_x000D_
// MDN hibrid soltuion_x000D_
// Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#Using_apply_and_built-in_functions_x000D_
function minOfArray(arr) {_x000D_
var min = Infinity;_x000D_
var QUANTUM = 32768;_x000D_
_x000D_
for (var i = 0, len = arr.length; i < len; i += QUANTUM) {_x000D_
var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));_x000D_
min = Math.min(submin, min);_x000D_
}_x000D_
_x000D_
return min;_x000D_
}_x000D_
_x000D_
minOfArray(testArray);_x000D_
_x000D_
function maxOfArray(arr) {_x000D_
var max = -Infinity;_x000D_
var QUANTUM = 32768;_x000D_
_x000D_
for (var i = 0, len = arr.length; i < len; i += QUANTUM) {_x000D_
var submax = Math.max.apply(null, arr.slice(i, Math.max(i + QUANTUM, len)));_x000D_
max = Math.max(submax, max);_x000D_
}_x000D_
_x000D_
return max;_x000D_
}_x000D_
_x000D_
maxOfArray(testArray);
_x000D_