How can I easily obtain the min and max values from a JavaScript Array?
Example code:
var arr = new Array();
arr[0] = 100;
arr[1] = 0;
arr[2] = 50;
// something like (but it doesn't have to be)
arr.min(); // return 0
arr.max(); // return 100
How can I easily obtain the min and max values from a JavaScript Array?
Example code:
var arr = new Array();
arr[0] = 100;
arr[1] = 0;
arr[2] = 50;
// something like (but it doesn't have to be)
arr.min(); // return 0
arr.max(); // return 100
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;
}
You can use Array.sort but you'll have to write a simple number sorting function since the default is alphabetic.
Then you can grab arr[0]
and arr[arr.length-1]
to get min and max.
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)
}
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);
Is this homework? You need to add a prototype to the array class which defines a function for min and max and then write some code that traverses the array storing the greatest or least value it's found.
For fun, I'm going to do half of this for you with jQuery:
x=Array();
jQuery.extend(x,{
min:function(){
var n=Number.MAX_VALUE;
for(i=0;i<this.length;i++){
if(this[i]<n){
n=this[i];
}}
return n;},
max:function(){var n=Number.MIN_VALUE;for(i=0;i<this.length;i++){if(this[i]>n){n=this[i];}}return n;}
});
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.
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.
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.