在JavaScript中查找数组的min/max元素

如何轻松获取JavaScript数组的min或max元素?

伪代码示例:

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

这可能符合您的目的。

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

您可以使用Array.sort但必须编写一个简单的数字排序函数,因为默认值是字母。

请看这里的示例2。

然后你可以抓取arr[0]arr[arr.length-1]来获取min和max。

如何增强内置Array对象以使用#0/#1代替:

Array.prototype.max = function() {return Math.max.apply(null, this);};
Array.prototype.min = function() {return Math.min.apply(null, this);};
let p = [35,2,65,7,8,9,12,121,33,99];
console.log(`Max value is: ${p.max()}` +`\nMin value is: ${p.min()}`);

这是一个JSFiddle

增强内置可能会导致与其他库的冲突(有些人看到了),所以你可能更愿意直接apply'ingMath.xxx()到你的数组:

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

或者,假设您的浏览器支持ECMAScript 6,您可以使用扩展语法,其功能类似于apply方法:

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

迭代,边走边跟踪。

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

如果数组中没有元素,这将使min/max为空。如果数组有任何元素,将一次性设置min和max。

您还可以使用上面的range方法扩展Array,以允许重用并提高易读性。参见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 }};

用作

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

如果你使用的是原型,ChaosPandion的解决方案是有效的。如果不是,考虑一下:

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

如果数组值不是整数,上述将返回NaN,因此您应该构建一些功能来避免这种情况。否则这将起作用。

你可以通过扩展Array类型来做到这一点:

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

这里提升(John Resig)

其他人已经给出了一些解决方案,其中它们增加了Array.prototype。我在这个答案中想要的只是澄清它应该是Math.min.apply( Math, array )还是Math.min.apply( null, array )那么应该使用什么上下文,#3还是#4?

当将null作为上下文传递给apply时,上下文将默认为全局对象(浏览器中的window对象)。将Math对象作为上下文传递是正确的解决方案,但传递null也不会受到伤害。这是一个装饰Math.max函数时null可能会引起麻烦的示例:

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

上面将抛出一个异常,因为this.foo将被评估为window.foo,即undefined。如果我们将null替换为Math,事情将按预期工作,字符串“foo”将打印到屏幕上(我使用Mozilla Rhino测试了这一点)。

你几乎可以假设没有人装饰过Math.max,所以传递null将没有问题。

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

有关详细讨论,请参阅:http://aaroncrane.co.uk/2008/11/javascript_max_api/

对于大数组(~10个元素),Math.minMath.max在node.js.中产生RangeError(超出最大调用堆栈大小)

对于大数组,一个快速而肮脏的解决方案是:

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

如果你使用的是prototype.js框架,那么这段代码可以正常工作:

arr.min();arr.max();

记录在这里:用于max的Javascript原型框架

我用这种方式解决了我的问题:

    var strDiv  = "4,8,5,1"var arrayDivs   = strDiv.split(",")var str = "";
for (i=0;i<arrayDivs.length;i++){if (i<arrayDivs.length-1){str = str + eval('arrayDivs['+i+']')+',';}else if (i==arrayDivs.length-1){str = str + eval('arrayDivs['+i+']');}}
str = 'Math.max(' + str + ')';var numMax = eval(str);

我希望我有帮助。

最好的问候。

还有一种方法可以做到:

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

用法:

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

创建一个简单的对象

var myArray = new Array();
myArray = [10,12,14,100];
var getMaxHeight = {hight : function( array ){ return Math.max.apply( Math, array );}
getMaxHeight.hight(myArray);

对于大数组(~10个元素),Math.minMath.max都会在Node.js.中产生以下错误

RangeError:超出最大调用堆栈大小

更健壮的解决方案是不将每个元素添加到调用堆栈中,而是传递一个数组:

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

如果您担心速度,以下代码比我的计算机上的Math.max.apply快约3倍。请参阅https://jsben.ch/JPOyL

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

如果您的数组包含字符串而不是数字,您还需要将它们强制转换为数字。下面的代码可以做到这一点,但它会使代码在我的机器上减慢约10倍。请参阅https://jsben.ch/uPipD

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

如果你需要性能,那么这是小数组的最佳方式:

var min = 99999;var max = 0;for(var i = 0; i < v.length; i++){if(v[i] < min){min = v[i];}if(v[i] >= max){max = v[i];}}
minHeight = Math.min.apply({},YourArray);minKey    = getCertainKey(YourArray,minHeight);maxHeight = Math.max.apply({},YourArray);maxKey    = getCertainKey(YourArray,minHeight);function getCertainKey(array,certainValue){for(var key in array){if (array[key]==certainValue)return key;}}

我很惊讶没有提到减少功能。

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

这是从对象数组中获取最大值的一种方法。创建一个副本(带切片),然后按降序对副本进行排序并获取第一个项目。

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;

我喜欢Linus的duce()方法,特别是对于大型数组。但只要你知道你需要min和max,为什么要迭代数组两次?

Array.prototype.minmax = function () {return this.reduce(function (p, v) {return [(p[0] < v ? p[0] : v), (p[1] > v ? p[1] : v)];}, [this[0], this[0]]);}

当然,如果你更喜欢迭代方法,你也可以这样做:

Array.prototype.minmax = function () {var mn = this[0], mx = this[0];this.forEach(function (v) {if (v < mn) mn = v;if (v > mx) mx = v;});return [mn, mx];};

我也有同样的问题,我需要获取数组的最小值和最大值,令我惊讶的是,数组没有内置函数。在阅读了很多之后,我决定自己测试“前3名”解决方案:

  1. 离散解决方案:一个for循环,根据当前的max和/或min值检查数组的每个元素;
  2. APPLY解决方案:将数组发送到Math.max和/或Math.min内部函数使用应用(空,数组);
  3. REDUCE解决方案:使用duce(函数)对数组的每个元素递归检查。

测试代码是这样的:

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

数组A充满了100,000个随机整数,每个函数在Mozilla Firefox 28.0上执行了10,000次,在配备Windows Vista的Intel Pentium 4 2.99GHz桌面上。泰晤士报以秒为单位,由performance.now()函数检索。结果是这些,有3个小数位和均方差:

  1. 离散解:平均值=0.161s,sd=0.078
  2. 适用解决方案:平均值=3.571s,sd=0.487
  3. REDUCE解决方案:平均值=0.350,sd=0.044

REDUCE解决方案比离散解决方案慢117%。APPLY解决方案更差,比离散解决方案慢2118%。此外,正如Peter观察到的,它不适用于大型数组(大约超过1,000,000个元素)。

此外,为了完成测试,我测试了这个扩展的离散代码:

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

时间:平均值=0.218s,sd=0.094

因此,它比简单的离散解决方案慢35%,但它一次检索最大值和最小值(任何其他解决方案至少需要两倍的时间来检索它们)。一旦OP需要这两个值,离散解决方案将是最佳选择(即使是两个独立的函数,一个用于计算最大值,另一个用于计算最小值,它们的性能将优于第二好的REDUCE解决方案)。

如果您使用库<强>sugar.js,您可以按照您的建议编写arr.min()arr.max()。您还可以从非数字数组中获取最小值和最大值。

min(map, all=false)返回数组中的元素最低值。map可以是映射要检查的值的函数或作为快捷方式的字符串。如果全部为真,将返回所有min数组中的值。

max(map, all=false)返回数组中的元素最大值。map可能是映射要检查的值的函数或作为快捷方式的字符串。如果all为true,将返回所有max数组中的值。

示例:

[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"]

Lo-Dash<强>underscore.js这样的库也提供了类似的强大的min和max函数:

来自Lo-Dash的示例:

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

您可以在项目中的任何地方使用以下函数:

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

然后你可以调用传递数组的函数:

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

简单的东西,真的。

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

当意图是调用带有参数值列表的可变变量函数时,通常使用.apply,例如。

#0函数返回零个或多个数字中最大的一个。

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

Math.max()方法不允许传入数组。如果您有一个需要获得最大值的值列表,您通常会使用Function.prototype.apply()调用此函数,例如:

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

但是,从ECMAScript 6开始,您可以使用点差算子

扩展运算符允许在需要多个参数(用于函数调用)或多个元素(用于数组文字)的地方扩展表达式。

使用扩展运算符,上面的内容可以重写为:

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

使用可变参数运算符调用函数时,您甚至可以添加其他值,例如。

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

奖金:

扩展运算符使您能够使用数组文字语法在ES5中需要回退到命令式代码的情况下创建新数组,使用pushsplice等的组合。

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

tl; dr

// 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];}}

MDN解决方案

#0上的官方MDN文档已经涵盖了这个问题:

以下函数使用Function.prototype.apply()查找数字数组中的最大元素。getMaxOfArray([1, 2, 3])等效于Math.max(1, 2, 3),但您可以在以编程方式构造的任何大小的数组上使用getMaxOfArray()

function getMaxOfArray(numArray) {return Math.max.apply(null, numArray);}

或者使用新的点差算子,获取数组的最大值变得容易得多。

var arr = [1, 2, 3];var max = Math.max(...arr);

数组的最大大小

根据MDNapply和传播解决方案的限制为65536,来自最大参数数的限制:

但要注意:以这种方式使用应用程序,你会冒超过JavaScript引擎参数长度限制的风险。应用参数太多(想想超过数万个参数)的函数的后果因引擎而异(JavaScriptCore的硬编码参数限制为65536),因为限制(甚至任何过大堆栈行为的性质)是未指定的。一些引擎会抛出异常。更有害的是,其他引擎会任意限制实际传递给应用函数的参数数量。为了说明后一种情况:如果这样的引擎有四个参数的限制(实际限制当然要高得多),就好像参数5、6、2、3被传递到上面的例子中,而不是整个数组。

它们甚至提供了一种混合解决方案,与其他解决方案相比,它的性能并不是很好。有关更多信息,请参阅下面的性能测试。

在2019年实际限制是调用堆栈的最大大小。对于基于现代Chromium的桌面浏览器,这意味着当涉及到使用apply或传播实际上,只有数字数组的最大大小是~120000查找min/max时。在此之上,将出现堆栈溢出并抛出以下错误:

RangeError:超出最大调用堆栈大小

使用下面的脚本(基于这篇博客文章),通过捕获该错误,您可以计算特定环境的限制。

警告!运行此脚本需要时间,根据系统的性能,它可能会减慢或崩溃您的浏览器/系统!

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

大型阵列的性能

基于网络逃逸注释中的测试,我创建了一些基准,在具有100000项的仅随机数数组上测试5种不同的方法。

2019年,结果显示标准回路(BTW没有大小限制)在任何地方都是最快的。#0和传播紧随其后,然后是MDN的混合解决方案,然后是reduce最慢。

几乎所有的测试都得出了相同的结果,除了一个传播速度最慢的测试。

如果您升级数组以拥有100万项,则事情开始中断,您将标准循环作为快速解决方案而reduce作为较慢的解决方案。

JSPerf基准测试

jsperf.com不同解决方案的基准测试结果,以找到数组的min/max项

JSBen基准测试

jsben.com不同解决方案的基准测试结果,以找到数组的min/max项

JSBench.me基准测试

jsbench.me不同解决方案的基准测试结果,以找到数组的min/max项

基准源代码

var testArrayLength = 100000var testArray = Array.from({length: testArrayLength}, () => Math.floor(Math.random() * 2000000));
// ES6 spreadMath.min(...testArray);Math.max(...testArray);
// reducetestArray.reduce(function(a, b) {return Math.max(a, b);});testArray.reduce(function(a, b) {return Math.min(a, b);});
// applyMath.min.apply(Math, testArray);Math.max.apply(Math, testArray);
// standard looplet 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_functionsfunction 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);

如果您像我一样偏执地使用Math.max.apply(给定大型数组根据MDN时可能会导致错误),请尝试以下操作:

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

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

不幸的是,匿名函数是必要的(而不是使用Math.max.bind(Math),因为reduce不仅将ab传递给它的函数,而且还传递i和对数组本身的引用,所以我们必须确保我们不会尝试调用max

插入用逗号分隔的数字,然后单击要调用的事件,即获取最大或最小数字。

        function maximumNumber() {       
var numberValue = document.myForm.number.value.split(",");var numberArray = [];    
for (var i = 0, len = numberValue.length; i < len; i += 1) {    
numberArray.push(+numberValue[i]);    
var largestNumber = numberArray.reduce(function (x, y) {return (x > y) ? x : y;});}    
document.getElementById("numberOutput").value = largestNumber;    
}    
function minimumNumber() {  
var numberValue = document.myForm.number.value.split(",");var numberArray = [];    
for (var i = 0, len = numberValue.length; i < len; i += 1) {    
numberArray.push(+numberValue[i]);    
var smallestNumber = numberArray.reduce(function (x, y) {return (x < y) ? x : y;});}    
document.getElementById("numberOutput").value = smallestNumber;    
}    
    
function restrictCharacters(evt) {    
evt = (evt) ? evt : window.event;var charCode = (evt.which) ? evt.which : evt.keyCode;if (((charCode >= '48') && (charCode <= '57')) || (charCode == '44')) {return true;}else {return false;}}
    <div><form name="myForm"><table><tr><td>Insert Number</td>               
<td><input type="text" name="number" id="number" onkeypress="return restrictCharacters(event);" /></td>                
<td><input type="button" value="Maximum" onclick="maximumNumber();" /></td>                
<td><input type="button" value="Minimum" onclick="minimumNumber();"/></td>                
<td><input type="text" id="numberOutput" name="numberOutput" /></td>    
</tr></table></form></div>

如果你有复杂的对象,你可以使用排序…例如:如果我想得到包含以下对象的MAX/MIN值的项目。

var objs= [{name:"Apple",value:3},{name:"Love",value:32},{name:"Cheese",value:1},{name:"Pork",value:77},{name:"Xmas",value:99}];

我会做一个排序:

objs.sort(function(a, b){return a.value-b.value});

然后:objs[0]是最小值,objs[objs.length-1]是最大值。

为了防止“max”和“min”在“for… in”循环中列出:

Object.defineProperty(Array.prototype, "max", {enumerable: false,configurable: false,writable: false,value: function() {return Math.max.apply(null, this);}});Object.defineProperty(Array.prototype, "min", {enumerable: false,configurable: false,writable: false,value: function() {return Math.min.apply(null, this);}});

用法:

var x = [10,23,44,21,5];x.max(); //44x.min(); //5

您可能不想向Array原型添加方法,这可能会与其他库冲突。

我已经看到了很多使用for每个的例子,我不推荐用于大型数组,因为它的性能与for循环相比很差。https://coderwall.com/p/kvzbpa/don-t-use-array-foreach-use-for-instead

还有Math.max(Math, [1,2,3]);总是给我NaN?

function minArray(a) {var min=a[0]; for(var i=0,j=a.length;i<j;i++){min=a[i]<min?a[i]:min;}return min;}
function maxArray(a) {var max=a[0]; for(var i=0,j=a.length;i<j;i++){max=a[i]>max?a[i]:max;}return max;}
minArray([1,2,3]); // returns 1

如果你有一个对象数组,下面的minArray()函数示例将接受2个参数,第一个是数组,第二个是要比较的对象键值的键名。在这种情况下,函数将返回具有最小给定键值的数组的索引。

function minArray(a, key) {var min, i, j, index=0;if(!key) {min=a[0];for(i=0,j=a.length;i<j;i++){min=a[i]<min?a[i]:min;}return min;}min=a[0][key];for(i=0,j=a.length;i<j;i++){if(a[i][key]<min) {min = a[i][key];index = i;}}return index;}
var a = [{fee: 9}, {fee: 2}, {fee: 5}];
minArray(a, "fee"); // returns 1, as 1 is the proper array index for the 2nd array element.

线性、几乎纯粹的功能方法

var min=[0, 29, 25].map((function(max) {max=-Infinity; return function(e) {return max=Math.max(max, e);}})())[0]

更多示例:

查找分钟

function getMin(arr) {return (ar || [0, 29, 25]).map((function(max) {max=-Infinity; return function(e) {return max=Math.max(max, e);}})())[0];}

或使用带有变量闭包的Array.map方法

function getMin(arrObjs) {return (arrObjs || [{val: 0}, {val: 29}, {val: 25}]).map((function(max) {max=-Infinity; return function(e) {return max=(max.val>e.val?max:e);}})())[0];}

查找最大值

function getMax(arr) {return (ar || [0, 29, 25]).map((function(v) {v=Infinity; return function(e) {return v=Math.min(v, e);}})())[0];}

对于对象数组

function getMax(arrObjs) {return (arrObjs || [{val: 0}, {val: 29}, {val: 25}]).map((function(v) {v=-Infinity; return function(e) {return v=(v.val<e.val?v:e);}})())[0];}

使用Math.max()Math.min()

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

以下函数使用Function.prototype.apply()查找数字数组中的最大元素。getMaxOfArray([1, 2, 3])等效于Math.max(1, 2, 3),但您可以在以编程方式构造的任何大小的数组上使用getMaxOfArray()

function getMaxOfArray(numArray) {return Math.max.apply(null, numArray);}

或者使用新的扩展运算符,获取数组的最大值变得容易得多。

var arr = [1, 2, 3];var max = Math.max(...arr); // 3var min = Math.min(...arr); // 1

使用扩展运算符(ES6)

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

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

下面的脚本在ndoejs中为我工作:

 var numbers = [1, 2, 3, 4];console.log('Value:: ' + Math.max.apply(null, numbers) ); // 4

我想我会分享我简单易懂的解决方案。

对于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);

对于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);

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

这对我有用。

以下代码适用于我:

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

找到元素Array上的最小值的一个简单解决方案是使用Array原型函数reduce

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

或者使用JavaScript的内置Math. Min()函数(感谢@Tenflex):

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

这将min设置为A[0],然后检查A[1]...A[n]是否严格小于当前的min。如果A[i] < min,则min更新为A[i]。当处理完所有数组元素后,返回min作为结果。

编辑:包含最小值的位置:

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 }

两种方法更简单和简单:

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

方式1

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

方式2

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

替代方法


Math.minMath.max是从项目集合中获取最小和最大项目的好方法,但是重要的是要注意它可能附带的一些空洞。

将它们与包含大量项目(超过10个项目,取决于用户的浏览器)的数组一起使用很可能会崩溃并给出以下错误消息:

const arr = Array.from(Array(1000000).keys());Math.min(arr);Math.max(arr);

未捕获的RangeError:超出最大调用堆栈大小

更新
最新的浏览器可能会返回NaN。这可能是处理错误的更好方法,但它还不能解决问题。

相反,考虑使用这样的东西:

function maxValue(arr) {return arr.reduce((max, val) => max > val ? max : val)}

或者更好的运行时:

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

或者同时获取min和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] });}

或者使用更好的运行时*:

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

*测试了1,000,000个项目:
只是为了参考,第一个函数运行时间(在我的机器上)是15.84ms,而第二个函数只有4.32ms。

这是另一个示例。从带有文件夹的数组中计算最大/最小值。

let array = [100, 0, 50];var func = _.over(Math.max, Math.min);var [max, min] = func(...array);// => [100, 0]console.log(max);console.log(min);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

let arr = [2,5,3,5,6,7,1];
let max = Math.max(...arr); // 7let min = Math.min(...arr); // 1

试试看

let max= a=> a.reduce((m,x)=> m>x ? m:x);let min= a=> a.reduce((m,x)=> m<x ? m:x);

let max= a=> a.reduce((m,x)=> m>x ? m:x);let min= a=> a.reduce((m,x)=> m<x ? m:x);
// TEST - pixel bufferlet arr = Array(200*800*4).fill(0);arr.forEach((x,i)=> arr[i]=100-i%101);
console.log('Max', max(arr));console.log('Min', min(arr))

对于Math.min/max(+应用),我们得到错误:

超出最大调用堆栈大小(Chrome74.0.3729.131)

// TEST - pixel bufferlet arr = Array(200*800*4).fill(0);arr.forEach((x,i)=> arr[i]=100-i%101);
// Exception: Maximum call stack size exceeded
try {let max1= Math.max(...arr);} catch(e) { console.error('Math.max :', e.message) }
try {let max2= Math.max.apply(null, arr);} catch(e) { console.error('Math.max.apply :', e.message) }

// same for min

这是一个简单的vanilla JS方法。

function getMinArrayVal(seq){var minVal = seq[0];for(var i = 0; i<seq.length-1; i++){if(minVal < seq[i+1]){continue;} else {minVal = seq[i+1];}}return minVal;}

问题的递归解决方案

const findMinMax = (arr, max, min, i) => arr.length === i ? {min,max} :findMinMax(arr,arr[i] > max ? arr[i] : max,arr[i] < min ? arr[i] : min,++i)
const arr = [5, 34, 2, 1, 6, 7, 9, 3];const max = findMinMax(arr, arr[0], arr[1], 0)console.log(max);

你可以用Lodash的方法

_.max([4, 2, 8, 6]);returns => 8

https://lodash.com/docs/4.17.15#max

_.min([4, 2, 8, 6]);returns => 2

https://lodash.com/docs/4.17.15#min

除了使用数学函数max和min之外,另一个要使用的函数是内置的sort()函数

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

为您提供数字数组中的最大值。

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

为您提供数字数组中的最小值。

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)

对于包含对象而不是数字的数组:

arr = [{ name: 'a', value: 5 },{ name: 'b', value: 3 },{ name: 'c', value: 4 }]

您可以使用reduce来获取具有最小值(min)的元素

arr.reduce((a, b) => a.value < b.value ? a : b)// { name: 'b', value: 3 }

或最大值(max)

arr.reduce((a, b) => a.value > b.value ? a : b)// { name: 'a', value: 5 }

对于一个简洁、现代的解决方案,可以对数组执行#0操作,跟踪当前的最小值和最大值,因此数组只迭代一次(这是最佳的)。

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

为了只找到最小值或最大值,我们可以以几乎相同的方式使用执行缩减操作,但我们只需要跟踪之前的最佳值。这种方法比使用apply更好,因为当数组对堆栈来说太大时,它不会导致错误。

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

让数组=[267,306,108]设最长=Math.max(…数组);

令arr=[20,8,29,76,7,21,9]
Math.max.apply(数学 ); // 76

嗯,我想用下面的方式来做这件事

const findMaxAndMin = (arr) => {if (arr.length <= 0) return -1;let min = arr[0];let max = arr[0];arr.forEach((n) => {n > max ? (max = n) : false;n < min ? (min = n) : false;});return [min, max];};

另一种解决方案

   let arr = [1,10,25,15,31,5,7,101];let sortedArr = arr.sort((a, b) => a - b)
let min = sortedArr[0];let max = sortedArr[arr.length-1]
console.log(`min => ${min}. Max => ${max}`)

截图

替代鞋底

class SmallestIntegerFinder {findSmallestInt(args) {return args.reduce((min,item)=>{ return (min<item ? min : item)});}}
class SmallestIntegerFinder {findSmallestInt(args) {return Math.min(...args)}}
class SmallestIntegerFinder {findSmallestInt(args) {return Math.min.apply(null, args);}}
class SmallestIntegerFinder {findSmallestInt(args) {args.sort(function(a, b) {return a - b; } )return args[0];}}

出于学习目的,您可以通过使用变量和for循环来实现,而无需使用内置函数。

// Input sample data to the functionvar arr = [-1, 0, 3, 100, 99, 2, 99];// Just to show the resultconsole.log(findMinMax(arr));
function findMinMax(arr) {let arraySize = arr.length;if (arraySize > 0) {var MaxNumber = MinNumber = arr[0];for (var i = 0; i <= arraySize; i++) {if (arr[i] > MaxNumber) {MaxNumber = arr[i];}else if(arr[i] < MinNumber) {MinNumber = arr[i];}}var minMax = [MinNumber,MaxNumber];return minMax;} else {return 0;}}

为了增加这里的许多好答案,这里有一个打字稿版本,可以处理一些值为undefined的列表。

如何使用它:

const testDates = [undefined,new Date('July 30, 1986'),new Date('July 31, 1986'),new Date('August 1, 1986'),]const max: Date|undefined = arrayMax(testDates); // Fri Aug 01 1986const min: Date|undefined = arrayMin(testDates); // Min: Wed Jul 30 1986const test: Date = arrayMin(testDates); // Static type errorconst anotherTest: undefined = arrayMin(testDates); // Static type error

定义(notEmpty定义来自这篇文章):

function arrayMax<T>(values?: (T | null | undefined)[]): T | undefined {const nonEmptyValues = filterEmpty(values);if (nonEmptyValues.length === 0) {return undefined;}return nonEmptyValues.reduce((a, b) => (a >= b ? a : b), nonEmptyValues[0]);}
function arrayMin<T>(values?: (T | null | undefined)[]): T | undefined {const nonEmptyValues = filterEmpty(values);if (nonEmptyValues.length === 0) {return undefined;}return nonEmptyValues.reduce((a, b) => (a <= b ? a : b), nonEmptyValues[0]);}
function filterEmpty<T>(values?: (T | null | undefined)[] | null): T[] {return values?.filter(notEmpty) ?? [];}
function notEmpty<T>(value: T | null | undefined): value is T {if (value === null || value === undefined) return false;const testDummy: T = value;return true;}

我没有将Math.max函数用作建议留档,因为这样我就可以将此函数用于任何可比较的对象(如果您知道如何键入this,请告诉我,以便我可以更好地定义T)。

在这个时代(2022年),从数组中获取min+max的最有效方法是通过reduce在一次迭代中进行。

  • 在JavaScript中:
const arr = [3, 0, -2, 5, 9, 4];
const i = arr.reduce((p, c) => {p.min = c < p.min ? c : p.min ?? c;p.max = c > p.max ? c : p.max ?? c;return p;}, {min: undefined, max: undefined});
console.log(i); //=> { min: -2, max: 9 }

当输入没有数据时,它将输出{min: undefined, max: undefined}

在TypeScript中,您只需添加类型转换,因此返回类型被推断为{min: number, max: number},而不是{min: any, max: any}

const arr = [3, 0, -2, 5, 9, 4];
const i = arr.reduce((p, c) => {p.min = c < p.min ? c : p.min ?? c;p.max = c > p.max ? c : p.max ?? c;return p;}, {min: undefined as number, max: undefined as number});//=> {min: number, max: number}
console.log(i); //=> { min: -2, max: 9 }

更新

kiran goud注释之后,这里有一个使用数组而不是对象的替代方案:

const i = arr.reduce((p, c) => {p[0] = c < p[0] ? c : p[0] ?? c;p[1] = c > p[1] ? c : p[1] ?? c;return p;}, [undefined, undefined]);
console.log(i); //=> [-2, 9]