在JavaScript中查找数组的最小/最大元素

如何轻松获得JavaScript数组的最小或最大元素?

示例伪代码:

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

如何增加内置的数组对象来使用Math.max / Math.min来代替:

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

这是一个JSFiddle

增加内build插件可能会导致与其他库(有些人会看到)发生冲突,所以您可能会更习惯于直接apply Math.xxx()应用于您的数组:

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

或者,假设您的浏览器支持ECMAScript 6,则可以使用与apply方法类似的spread运算符 :

 var min = Math.min( ...arr ), max = Math.max( ...arr ); 
 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:超出最大调用堆栈大小

更可靠的解决scheme是不将每个元素添加到调用堆栈,而是传递一个数组:

 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倍。 请参阅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; }; 

如果您的数组包含string而不是数字,则还需要将其强制转换为数字。 下面的代码就是这样做的,但是它会在我的机器上减慢〜10倍的代码速度。 请参阅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; }; 

使用扩展运算符(ES6)

 Math.max(...array); // the same with "min" => Math.min(...array); 
 const array = [10, 2, 33, 4, 5]; console.log( Math.max(...array) ) 

如果你像我一样偏执使用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的function,而且i和一个参考数组本身,所以我们必须确保我们不要也不要试图打电话给这些人。

.apply程序通常用于当用参数值列表调用可变参数时

Math.max([value1[,value2, ...]])函数返回零个或多个数字中最大的一个。

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

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

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

但是,从ECMAScript 6开始,您可以使用扩展运算符 :

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

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

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

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

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

奖金:

Spread操作符使您能够使用数组文本语法来创build新的数组,在ES5中,您需要使用pushsplice等组合来回退到命令式代码。

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

TL;博士

 var max = Math.max(...arrayOfNumbers); 

官方的Math.max() 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); 

你可以通过扩展数组types来实现:

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

从这里加强(John Resig)

其他人已经提供了一些解决scheme,他们增加了Array.prototype 。 我想在这个答案是澄清是否应Math.min.apply( Math, array )Math.min.apply( null, array )那么应该使用什么上下文, Math还是null

当将null作为上下文apply ,上下文将默认为全局对象(在浏览器的情况下为window对象)。 传递Math对象作为上下文将是正确的解决scheme,但它也不会伤害传递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); 

以上将抛出一个exception,因为this.foo将被评估为window.foo ,这是undefined 。 如果我们用Mathreplacenull ,事情将按预期工作,string“foo”将被打印到屏幕上(我使用Mozilla Rhinotesting了这个)。

你几乎可以假设没有人装饰Math.max所以传递null将毫无问题地工作。

还有一种方法可以做到这一点:

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

用法:

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

我很惊讶没有人提到减lessfunction。

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

对于大数组(〜10个元素), Math.minMath.max会在node.js中引发RangeError(超出最大调用堆栈大小)。

对于大数组,一个快速和肮脏的解决scheme是:

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

我有同样的问题,我需要获得一个数组的最小值和最大值,令我惊讶的是,没有数组的内置函数。 阅读了很多之后,我决定自己testing“前三名”解决scheme:

  1. 离散解决scheme:一个FOR循环来检查数组的每个元素与当前的最大值和/或最小值;
  2. APPLY解决scheme:使用apply(null,array)将数组发送到Math.max和/或Math.min内部函数。
  3. REDUCE解决scheme:使用reduce(function)对数组中的每个元素进行recursion检查。

testing代码是这样的:

 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个随机整数,每个函数在带有Windows Vista的Intel Pentium 4 2.99GHz桌面的Mozilla Firefox 28.0上执行10,000次。 时间以秒为单位,通过performance.now()函数检索。 结果是这些,有3个小数位和标准偏差:

  1. 离散解:平均值= 0.161s,sd = 0.078
  2. 申请解决scheme:平均= 3.571s,sd = 0.487
  3. 减less解决scheme:平均= 0.350s,sd = 0.044

REDUCE解决scheme比分立式解决scheme慢117%。 APPLY解决scheme更糟,比分立解决scheme慢了2,118%。 此外,正如彼得所观察到的,它不适用于大型数组(大约有一百多万个元素)。

另外,为了完成testing,我testing了这个扩展的离散代码:

 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

因此,它比简单的离散解决scheme慢35%,但它一次检索最大值和最小值(任何其他解决scheme至less需要检索它们的两倍)。 一旦OP需要两个值,离散解决scheme将是最好的select(即使作为两个独立的function,一个用于计算最大值,另一个用于计算最小值,他们将胜过次优,REDUCE解决scheme)。

您可以在项目的任何位置使用以下function:

 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 

这可能适合你的目的。

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

迭代,保持跟踪。

 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为null。 如果数组有任何元素,将在一次传递中设置最小值和最大值。

你也可以使用上面的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); 

简单的东西,真的。

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

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

 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; 

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

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

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

对于分:

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

如果您使用原型,ChaosPandion的解决scheme就可以工作。 如果没有,请考虑这一点:

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

如果一个数组值不是一个整数,上面将返回NaN,所以你应该build立一些function来避免这种情况。 否则这将工作。

如果你正在使用prototype.js框架,那么这个代码将正常工作:

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

logging在这里: Javascript原型框架最大

如果你使用库糖sugar.js ,你可以写你的build议arr.min()arr.max() 。 您还可以从非数字数组中获取最小值和最大值。

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

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

例子:

 [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-Dashunderscore.js这样的库也提供了类似的强大的最小和最大函数:

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

我喜欢Linus的reduce()方法 ,特别是对于大型数组。 但只要你知道你需要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]; }; 

创build一个简单的对象

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

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

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

find元素Array的最小值的简单方法是使用Array原型函数reduce

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

这将min设置为A[0] ,然后检查A[1]...A[n]是否严格小于当前min

以下代码适用于我:

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