如何轻松获取JavaScript数组的最小或最大元素?
示例Psuedocode:
let array = [100, 0, 50] array.min() //=> 0 array.max() //=> 100
Roatin Marth.. 783
如何扩充内置的Array对象以使用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.
增强的内置插件可能会导致与其他库(一些人认为)的碰撞,所以你可能会更舒服只是apply
"荷兰国际集团Math.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 );
作为一名C#程序员,我需要强类型的问题. (28认同)
不要像这样增加内置原型.这不仅仅是与其他图书馆的冲突; 它也是关于浏览器本身在将来提供`.max`或`.min`方法的潜力.非常逼真的场景:*你使用这个答案.2016年,ES7或ES8规范`Array.max`和`Array.min`.与此版本不同,它们适用于字符串.你未来的同事试图用现在记录良好的原生`.max()`方法将数字字母最新的字符串放在一个数组中,但神秘地得到`NaN`.几个小时后,她发现这个代码,运行一个'git blame`,并诅咒你的名字.* (12认同)
我投票,因为提议的方法在堆栈帧中消耗O(n)内存,因此在大型数组上崩溃.在我的情况下,只有大约130000个数字足以崩溃nodejs. (10认同)
@HankH:传递`null`或`Math`或`{}`或者什么来对'apply()`或`call()`与结果无关.`Math.max`不会也不应该在内部引用`this`. (8认同)
只是分享一个jQuery错误,我正在使用上面的代码,这花了我很长时间来调试.除了iPad之外,jquery数组在所有内容上都能正常工作.我必须将数组转换为真正的本机数组才能工作.仅因某种原因影响单个设备`Math.max.apply(null,$ .makeArray(array));` (7认同)
@HankH:也许吧.`Math.max`类似于"静态"方法,所以内部没有有用的`this`实例(我希望).所以假设这是真的,调用它将在全局范围内运行它(即`window`),这相当于将`null`作为第一个参数传递给`apply` /`call`. (4认同)
不应该是"返回Math.max.apply(数学,这个);" 并且不返回Math.max.apply(null,this); (2认同)
@ChaosPandion:你是对的.这不适用于任何其他类型. (2认同)
...或者只是包装代码`if(!Array.max){...}`,这样如果浏览器确实添加了这些方法,它们就不会被替换. (2认同)
newspire.. 346
var max_of_array = Math.max.apply(Math, array);
如需全面讨论,请访问:http: //aaroncrane.co.uk/2008/11/javascript_max_api/
如何扩充内置的Array对象以使用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.
增强的内置插件可能会导致与其他库(一些人认为)的碰撞,所以你可能会更舒服只是apply
"荷兰国际集团Math.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 max_of_array = Math.max.apply(Math, array);
如需全面讨论,请访问:http: //aaroncrane.co.uk/2008/11/javascript_max_api/
对于大阵列(〜10⁷元素),Math.min
并且Math.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倍.请参见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; };
如果数组包含字符串而不是数字,则还需要将它们强制转换为数字.下面的代码可以做到这一点,但它会在我的机器上将代码减慢~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)
)
// 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];
}
}
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);
如果你像我一样偏执狂使用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
不只是传递a
和b
其功能,而且还i
和数组本身的引用,所以我们必须确保我们不会试图调用max
,以及那些.
.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开始,您可以使用spread运算符:
spread运算符允许在需要多个参数(用于函数调用)或多个元素(用于数组文字)的位置扩展表达式.
使用扩展运算符,可以重写上述内容:
Math.max(...[10, 20]); // 20 Math.max(...[-10, -20]); // -10 Math.max(...[-10, 20]); // 20
使用variadic运算符调用函数时,甚至可以添加其他值,例如
Math.max(...[10, 20], 50); // 50 Math.max(...[-10, -20], 50); // 50
奖金:
价差操作,您可以使用数组文本语法在ES5,你将需要退回到命令式代码的情况下创建新的阵列,使用的组合push
,splice
等等.
let foo = ['b', 'c']; let bar = ['a', ...foo, 'd', 'e']; // ['a', 'b', 'c', 'd', 'e']
您可以通过扩展Array类型来实现:
Array.max = function( array ){ return Math.max.apply( Math, array ); }; Array.min = function( array ){ return Math.min.apply( Math, array ); };
从这里开始(由John Resig提供)
找到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]
通过返回该值.
两种方式更简单:
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); });
其他人已经提出了一些可以增强的解决方案Array.prototype
.我在这个答案中想要的是澄清它是否应该是Math.min.apply( Math, array )
或Math.min.apply( null, array )
.那么应该使用什么背景,Math
或者null
?
当null
作为上下文传递时apply
,上下文将默认为全局对象(在window
浏览器的情况下为对象).将Math
对象作为上下文传递将是正确的解决方案,但它也不会伤害传递null
.这是一个null
在装饰Math.max
功能时可能会造成麻烦的例子:
// 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 arrayMax = Function.prototype.apply.bind(Math.max, null);
用法:
var max = arrayMax([2, 5, 1]);
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 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]
这可能适合您的目的.
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; }
对于大数组(~ 10⁷ 元素),Math.min
并Math.max
在node.js中产生RangeError(超出最大调用堆栈大小).
对于大型阵列,快速而肮脏的解决方案是:
Array.prototype.min = function() { var r = this[0]; this.forEach(function(v,i,a){if (v
17> Cyberknight..:我遇到了同样的问题,我需要获取数组的最小值和最大值,令我惊讶的是,没有内置的数组函数.经过大量阅读后,我决定自己测试"前3名"解决方案:
离散解决方案:一个FOR循环,用于检查数组中每个元素的当前最大值和/或最小值;
APPLY解决方案:使用apply(null,array)将数组发送到Math.max和/或Math.min内部函数;
REDUCE解决方案:使用reduce(function)对数组的每个元素进行检查.
测试代码是这样的:
function GetMaxDISCRETE(A) { var MaxX=A[0]; for (var X=0;Xc?p:c; }); } 阵列A填充了100,000个随机整数,每个函数在带有Windows Vista的intel Pentium 4 2.99GHz桌面上的Mozilla Firefox 28.0上执行10,000次.时间以秒为单位,由performance.now()函数检索.结果是这些,有3个小数位和标准差:
离散解:平均值= 0.161s,sd = 0.078
APPLY solution:mean = 3.571s,sd = 0.487
REDUCE解决方案:平均值= 0.350s,sd = 0.044
REDUCE解决方案比分立解决方案慢117%.APPLY解决方案更糟糕,比分立解决方案慢2,118%.此外,正如Peter所说,它不适用于大型阵列(大约超过1,000,000个元素).
另外,为了完成测试,我测试了这个扩展的离散代码:
var MaxX=A[0],MinX=A[0]; for (var X=0;XA[X]) MinX=A[X]; } 时间:平均值= 0.218s,sd = 0.094
因此,它比简单的离散解决方案慢35%,但它同时检索最大值和最小值(任何其他解决方案至少需要两倍才能检索它们).一旦OP需要两个值,离散解决方案将是最佳选择(即使是两个单独的函数,一个用于计算最大值,另一个用于计算最小值,它们将胜过第二个最好的REDUCE解决方案).
18> 小智..:您可以在项目的任何位置使用以下功能:
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
19> 小智..:以下代码适用于我:
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); });
20> Lior Elrom..:
Math.min和Math.max的
Math.min
和Math.max
都是递归运算其中最有可能crach的大阵列(大于〜10⁷项目).相反,你可以像这样使用旧的javascript循环:
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 vs第二个功能,只有4.32ms.
21> tvanfosson..:迭代,随时跟踪.
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.如果数组有任何元素,将在一次传递中设置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);
22> Ionut Necula..:我以为我会分享我简单易懂的解决方案.
对于分钟:
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);
23> 小智..:这是从一组对象中获取最大值的一种方法.创建一个副本(带有切片),然后按降序对副本进行排序并获取第一个项目.
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;
24> Brian..:简单的东西,真的.
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());
25> shilovk..:使用
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