How can I easily obtain the min or max element of a JavaScript Array?

Example Psuedocode:

let array = [100, 0, 50] array.min() //=> 0 array.max() //=> 100

Skip to content
# Find the min/max element of an Array in JavaScript

## The Question :

*847 people think this question is useful*
*The Question Comments :*
## The Answer 1

*875 people think this answer is useful*

## The Answer 2

*382 people think this answer is useful*
## The Answer 3

*214 people think this answer is useful*
## The Answer 4

*175 people think this answer is useful*
## The Answer 5

*123 people think this answer is useful*
## tl;dr

## MDN solution

## Maximum size of an array

## Performance on large arrays

### JSPerf benchmark

### JSBen benchmark

### JSBench.me benchmark

### Benchmark source code

## The Answer 6

*68 people think this answer is useful*
## The Answer 7

*40 people think this answer is useful*
## The Answer 8

*38 people think this answer is useful*
## The Answer 9

*23 people think this answer is useful*
## The Answer 10

*22 people think this answer is useful*
# Alternative Methods

## The Answer 11

*21 people think this answer is useful*
## The Answer 12

*15 people think this answer is useful*
## The Answer 13

*15 people think this answer is useful*
## The Answer 14

*13 people think this answer is useful*
## The Answer 15

*13 people think this answer is useful*
## The Answer 16

*12 people think this answer is useful*
## The Answer 17

*9 people think this answer is useful*
## The Answer 18

*8 people think this answer is useful*
## The Answer 19

*8 people think this answer is useful*
## The Answer 20

*8 people think this answer is useful*
## The Answer 21

*7 people think this answer is useful*
## The Answer 22

*6 people think this answer is useful*
## The Answer 23

*6 people think this answer is useful*
## The Answer 24

*5 people think this answer is useful*
## The Answer 25

*5 people think this answer is useful*
## The Answer 26

*5 people think this answer is useful*
## The Answer 27

*5 people think this answer is useful*
## The Answer 28

*5 people think this answer is useful*
## The Answer 29

*4 people think this answer is useful*
## The Answer 30

*4 people think this answer is useful*

2021-01-10

How can I easily obtain the min or max element of a JavaScript Array?

Example Psuedocode:

let array = [100, 0, 50] array.min() //=> 0 array.max() //=> 100

**Note:**With ECMAScript 6 you can use the new spread operator (three dots:`...`

) with`Math.max()`

like this:`Math.max(...[2, 5, 16, 1])`

. See my answer made from the MDN documentation.- here a benchmark for a speed comparison of the most common ways to do it: jsben.ch/#/1QuTg
**Without ES6**`Math.max.apply(null, [2,5,16,1])`

- In ES6, obtaining both the maximum and minimum can be done with only one
`reduce`

call.

How about augmenting the built-in Array object to use `Math.max`

/`Math.min`

instead:

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

Here is a **JSFiddle**.

Augmenting the built-ins can cause collisions with other libraries (some see), so you may be more comfortable with just `apply`

‘ing `Math.xxx()`

to your array directly:

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

Alternately, assuming your browser supports ECMAScript 6, you can use the spread operator which functions similarly to the `apply`

method:

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

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

For a full discussion see: http://aaroncrane.co.uk/2008/11/javascript_max_api/

For big arrays (~10⁷ elements), `Math.min`

and `Math.max`

both produces the following error in Node.js.

RangeError: Maximum call stack size exceeded

A more robust solution is to not add every element to the call stack, but to instead pass an array:

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

If you are concerned about speed, the following code is ~3 times faster then `Math.max.apply`

is on my computer. See 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; };

If your arrays contains strings instead of numbers, you also need to coerce them into numbers. The below code does that, but it slows the code down ~10 times on my machine. See 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; };

Using spread operator (ES6)

Math.max(...array); // the same with "min" => Math.min(...array);

const array = [10, 2, 33, 4, 5]; console.log( Math.max(...array) )

// 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 to`Math.max(1, 2, 3)`

, but you can use`getMaxOfArray()`

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)); for (i = 10000; i < 1000000; ++i) { testArray.push(Math.floor(Math.random() * 2000000)); try { Math.max.apply(null, testArray); } catch (e) { console.log(i); break; } }

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 var testArray = Array.from({length: testArrayLength}, () => Math.floor(Math.random() * 2000000)); // ES6 spread Math.min(...testArray); Math.max(...testArray); // reduce testArray.reduce(function(a, b) { return Math.max(a, b); }); testArray.reduce(function(a, b) { return Math.min(a, b); }); // apply Math.min.apply(Math, testArray); Math.max.apply(Math, testArray); // standard loop let max = testArray[0]; for (let i = 1; i < testArrayLength; ++i) { if (testArray[i] > max) { max = testArray[i]; } } let min = testArray[0]; for (let i = 1; i < testArrayLength; ++i) { if (testArray[i] < min) { min = testArray[i]; } } // MDN hibrid soltuion // Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#Using_apply_and_built-in_functions function minOfArray(arr) { var min = Infinity; var QUANTUM = 32768; for (var i = 0, len = arr.length; i < len; i += QUANTUM) { var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len))); min = Math.min(submin, min); } return min; } minOfArray(testArray); function maxOfArray(arr) { var max = -Infinity; var QUANTUM = 32768; for (var i = 0, len = arr.length; i < len; i += QUANTUM) { var submax = Math.max.apply(null, arr.slice(i, Math.max(i + QUANTUM, len))); max = Math.max(submax, max); } return max; } maxOfArray(testArray);

If you’re paranoid like me about using `Math.max.apply`

(which could cause errors when given large arrays according to MDN), try this:

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

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

The anonymous functions are unfortunately necessary (instead of using `Math.max.bind(Math)`

because `reduce`

doesn’t just pass `a`

and `b`

to its function, but also `i`

and a reference to the array itself, so we have to ensure we don’t try to call `max`

on those as well.

`.apply`

is often used when the intention is to invoke a variadic function with a list of argument values, e.g.

The `Math.max([value1[,value2, ...]])`

function returns the largest of zero or more numbers.

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

The `Math.max()`

method doesn’t allow you to pass in an array. If you have a list of values of which you need to get the largest, you would normally call this function using Function.prototype.apply(), e.g.

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

However, as of the **ECMAScript 6** you can use the spread operator:

The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.

Using the spread operator, the above can be rewritten as such:

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

When calling a function using the variadic operator, you can even add additional values, e.g.

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

**Bonus:**

Spread operator enables you to use the array literal syntax to create new arrays in situations where in ES5 you would need to fall back to imperative code, using a combination of `push`

, `splice`

, etc.

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

Two ways are shorter and easy:

let arr = [2, 6, 1, 0]

**Way 1**:

let max = Math.max.apply(null, arr)

**Way 2**:

let max = arr.reduce(function(a, b) { return Math.max(a, b); });

You do it by extending the Array type:

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

Boosted from here (by John Resig)

The `Math.min`

and `Math.max`

methods are both recursive operations that being added to the JS engine’s call stack, and most likely * crash* for an array that contains large number of items

(more than ~10⁷ items, depends on the user’s browser).

Math.max(…Array(1000000).keys());

Uncaught RangeError: Maximum call stack size exceeded

Instead, use something like so:

arr.reduce((max, val) => max > val ? max : val)

Or with better run-time:

function maxValue(arr) { let max = arr[0]; for (let val of arr) { if (val > max) { max = val; } } return max; }

Or to get both Min and Max:

function getMinMax(arr) { return arr.reduce(({min, max}, v) => ({ min: min < v ? min : v, max: max > v ? max : v, }), { min: arr[0], max: arr[0] }); }

Or with even better run-time*:

function getMinMax(arr) { let min = arr[0]; let max = arr[0]; let i = arr.length; while (i--) { min = arr[i] < min ? arr[i] : min; max = arr[i] > max ? arr[i] : max; } return { min, max }; }

* Tested with 1,000,000 items:

Just for a reference, the 1st function run-time (on my machine) was 15.84ms vs 2nd function with only 4.32ms.

A simple solution to find the minimum value over an `Array`

of elements is to use the `Array`

prototype function `reduce`

:

A = [4,3,-9,-2,2,1]; A.reduce((min, val) => val < min ? val : min, A[0]); // returns -9

or using JavaScript’s built-in Math.Min() function (thanks @Tenflex):

A.reduce((min,val) => Math.min(min,val), A[0]);

This sets `min`

to `A[0]`

, and then checks for `A[1]...A[n]`

whether it is strictly less than the current `min`

. If `A[i] < min`

then `min`

is updated to `A[i]`

. When all array elements has been processed, `min`

is returned as the result.

**EDIT**: Include position of minimum value:

A = [4,3,-9,-2,2,1]; A.reduce((min, val) => val < min._min ? {_min: val, _idx: min._curr, _curr: min._curr + 1} : {_min: min._min, _idx: min._idx, _curr: min._curr + 1}, {_min: A[0], _idx: 0, _curr: 0}); // returns { _min: -9, _idx: 2, _curr: 6 }

Others have already given some solutions in which they augment `Array.prototype`

. All I want in this answer is to clarify whether it should be `Math.min.apply( Math, array )`

or `Math.min.apply( null, array )`

. **So what context should be used, Math or null?**

When passing `null`

as a context to `apply`

, then the context will default to the global object (the `window`

object in the case of browsers). Passing the `Math`

object as the context would be the correct solution, but it won’t hurt passing `null`

either. Here’s an example when `null`

might cause trouble, when decorating the `Math.max`

function:

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

The above will throw an exception because `this.foo`

will be evaluated as `window.foo`

, which is `undefined`

. If we replace `null`

with `Math`

, things will work as expected and the string “foo” will be printed to the screen (I tested this using Mozilla Rhino).

You can pretty much assume that nobody has decorated `Math.max`

so, passing `null`

will work without problems.

One more way to do it:

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

Usage:

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

I am surprised not one mentiond the reduce function.

var arr = [1, 10, 5, 11, 2] var b = arr.reduce(function(previous,current){ return previous > current ? previous:current }); b => 11 arr => [1, 10, 5, 11, 2]

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/max

function getMaxOfArray(numArray) { return Math.max.apply(null, numArray); } var arr = [100, 0, 50]; console.log(getMaxOfArray(arr))

this worked for me.

This may suit your purposes.

Array.prototype.min = function(comparer) { if (this.length === 0) return null; if (this.length === 1) return this[0]; comparer = (comparer || Math.min); var v = this[0]; for (var i = 1; i < this.length; i++) { v = comparer(this[i], v); } return v; } Array.prototype.max = function(comparer) { if (this.length === 0) return null; if (this.length === 1) return this[0]; comparer = (comparer || Math.max); var v = this[0]; for (var i = 1; i < this.length; i++) { v = comparer(this[i], v); } return v; }

For big arrays (~10⁷ elements), `Math.min`

and `Math.max`

procuces a RangeError (Maximum call stack size exceeded) in node.js.

For big arrays, a quick & dirty solution is:

Array.prototype.min = function() { var r = this[0]; this.forEach(function(v,i,a){if (v<r) r=v;}); return r; };

I had the same problem, I needed to obtain the minimum and maximum values of an array and, to my surprise, there were no built-in functions for arrays. After reading a lot, I decided to test the “top 3” solutions myself:

- discrete solution: a FOR loop to check every element of the array against the current max and/or min value;
- APPLY solution: sending the array to the Math.max and/or Math.min internal functions using apply(null,array);
- REDUCE solution: recursing a check against every element of the array using reduce(function).

The test code was this:

function GetMaxDISCRETE(A) { var MaxX=A[0]; for (var X=0;X<A.length;X++) if (MaxX<A[X]) MaxX=A[X]; return MaxX; } function GetMaxAPPLY(A) { return Math.max.apply(null,A); } function GetMaxREDUCE(A) { return A.reduce(function(p,c) { return p>c?p:c; }); }

The array A was filled with 100,000 random integer numbers, each function was executed 10,000 times on Mozilla Firefox 28.0 on an intel Pentium 4 2.99GHz desktop with Windows Vista. The times are in seconds, retrieved by performance.now() function. The results were these, with 3 fractional digits and standard deviation:

- Discrete solution: mean=0.161s, sd=0.078
- APPLY solution: mean=3.571s, sd=0.487
- REDUCE solution: mean=0.350s, sd=0.044

The REDUCE solution was 117% slower than the discrete solution. The APPLY solution was the worse, 2,118% slower than the discrete solution. Besides, as Peter observed, it doesn’t work for large arrays (about more than 1,000,000 elements).

Also, to complete the tests, I tested this extended discrete code:

var MaxX=A[0],MinX=A[0]; for (var X=0;X<A.length;X++) { if (MaxX<A[X]) MaxX=A[X]; if (MinX>A[X]) MinX=A[X]; }

The timing: mean=0.218s, sd=0.094

So, it is 35% slower than the simple discrete solution, but it retrieves both the maximum and the minimum values at once (any other solution would take at least twice that to retrieve them). Once the OP needed both values, the discrete solution would be the best choice (even as two separate functions, one for calculating maximum and another for calculating minimum, they would outperform the second best, the REDUCE solution).

You can use the following function anywhere in your project:

function getMin(array){ return Math.min.apply(Math,array); } function getMax(array){ return Math.max.apply(Math,array); }

And then you can call the functions passing the array:

var myArray = [1,2,3,4,5,6,7]; var maximo = getMax(myArray); //return the highest number

The following code works for me :

var valueList = [10,4,17,9,3]; var maxValue = valueList.reduce(function(a, b) { return Math.max(a, b); }); var minValue = valueList.reduce(function(a, b) { return Math.min(a, b); });

Iterate through, keeping track as you go.

var min = null; var max = null; for (var i = 0, len = arr.length; i < len; ++i) { var elem = arr[i]; if (min === null || min > elem) min = elem; if (max === null || max < elem) max = elem; } alert( "min = " + min + ", max = " + max );

This will leave min/max null if there are no elements in the array. Will set min and max in one pass if the array has any elements.

You could also extend Array with a `range`

method using the above to allow reuse and improve on readability. See a working fiddle at http://jsfiddle.net/9C9fU/

Array.prototype.range = function() { var min = null, max = null, i, len; for (i = 0, len = this.length; i < len; ++i) { var elem = this[i]; if (min === null || min > elem) min = elem; if (max === null || max < elem) max = elem; } return { min: min, max: max } };

Used as

var arr = [3, 9, 22, -7, 44, 18, 7, 9, 15]; var range = arr.range(); console.log(range.min); console.log(range.max);

I thought I’d share my simple and easy to understand solution.

For the min:

var arr = [3, 4, 12, 1, 0, 5]; var min = arr[0]; for (var k = 1; k < arr.length; k++) { if (arr[k] < min) { min = arr[k]; } } console.log("Min is: " + min);

And for the max:

var arr = [3, 4, 12, 1, 0, 5]; var max = arr[0]; for (var k = 1; k < arr.length; k++) { if (arr[k] > max) { max = arr[k]; } } console.log("Max is: " + max);

Aside using the math function max and min, another function to use is the built in function of sort(): here we go

const nums = [12, 67, 58, 30].sort((x, y) => x - y) let min_val = nums[0] let max_val = nums[nums.length -1]

Simple stuff, really.

var arr = [10,20,30,40]; arr.max = function() { return Math.max.apply(Math, this); }; //attach max funct arr.min = function() { return Math.min.apply(Math, this); }; //attach min funct alert("min: " + arr.min() + " max: " + arr.max());

Here’s one way to get the max value from an array of objects. Create a copy (with slice), then sort the copy in descending order and grab the first item.

var myArray = [ {"ID": 1, "Cost": 200}, {"ID": 2, "Cost": 1000}, {"ID": 3, "Cost": 50}, {"ID": 4, "Cost": 500} ] maxsort = myArray.slice(0).sort(function(a, b) { return b.ID - a.ID })[0].ID;

Using `Math.max()`

or `Math.min()`

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

The following function uses `Function.prototype.apply()`

to find the maximum element in a numeric array. `getMaxOfArray([1, 2, 3])`

is equivalent to `Math.max(1, 2, 3)`

, but you can use `getMaxOfArray()`

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); // 3 var min = Math.min(...arr); // 1

array.sort((a, b) => b - a)[0];

Gives you the maximum value in an array of numbers.

array.sort((a, b) => a - b)[0];

Gives you the minimum value in an array of numbers.

let array = [0,20,45,85,41,5,7,85,90,111]; let maximum = array.sort((a, b) => b - a)[0]; let minimum = array.sort((a, b) => a - b)[0]; console.log(minimum, maximum)

For a concise, modern solution, one can perform a `reduce`

operation over the array, keeping track of the current minimum and maximum values, so the array is only iterated over once (which is optimal). Destructuring assignment is used here for succinctness.

let array = [100, 0, 50]; let [min, max] = array.reduce(([prevMin,prevMax], curr)=> [Math.min(prevMin, curr), Math.max(prevMax, curr)], [Infinity, -Infinity]); console.log("Min:", min); console.log("Max:", max);

To only find either the minimum or maximum, we can use perform a reduce operation in much the same way, but we only need to keep track of the previous optimal value. This method is better than using `apply`

as it will not cause errors when the array is too large for the stack.

const arr = [-1, 9, 3, -6, 35]; //Only find minimum const min = arr.reduce((a,b)=>Math.min(a,b), Infinity); console.log("Min:", min);//-6 //Only find maximum const max = arr.reduce((a,b)=>Math.max(a,b), -Infinity); console.log("Max:", max);//35

ChaosPandion’s solution works if you’re using protoype. If not, consider this:

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

The above will return NaN if an array value is not an integer so you should build some functionality to avoid that. Otherwise this will work.

If you use the library **sugar.js**, you can write **arr.min()** and **arr.max()** as you suggest. You can also get min and max values from non-numeric arrays.

min( map , all = false )Returns the element in the array with the lowest value. map may be a function mapping the value to be checked or a string acting as a shortcut. If all is true, will return all min values in an array.

max( map , all = false )Returns the element in the array with the greatest value. map may be a function mapping the value to be checked or a string acting as a shortcut. If all is true, will return all max values in an array.

Examples:

[1,2,3].min() == 1 ['fee','fo','fum'].min('length') == "fo" ['fee','fo','fum'].min('length', true) == ["fo"] ['fee','fo','fum'].min(function(n) { return n.length; }); == "fo" [{a:3,a:2}].min(function(n) { return n['a']; }) == {"a":2} ['fee','fo','fum'].max('length', true) == ["fee","fum"]

Libraries like **Lo-Dash** and **underscore.js** also provide similar powerful min and max functions:

Example from Lo-Dash:

_.max([4, 2, 8, 6]) == 8 var characters = [ { 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 } ]; _.max(characters, function(chr) { return chr.age; }) == { 'name': 'fred', 'age': 40 }