我怎样才能轻松地获得一个JavaScript数组的最小或最大元素?
伪代码示例:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
我怎样才能轻松地获得一个JavaScript数组的最小或最大元素?
伪代码示例:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
当前回答
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]; 令maximum = array。排序((a, b) => b - a)[0]; 令minimum = array。排序((a, b) => a - b)[0]; console.log(最小值,最大值)
其他回答
遍历,在执行过程中保持跟踪。
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为空。如果数组中有任何元素,将在一次传递中设置最小值和最大值。
您还可以使用上述方法使用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);
如何使用Math.max/Math扩展内置Array对象呢?最小值:
Array.prototype.max = function() { Math.max返回。应用(null,这); }; Array.prototype.min = function() { Math.min返回。应用(null,这); }; 令p = [35,2,65,7,8,9,12,121,33,99]; console.log('最大值为:${p.max()} ' + \nMin值为:${p.min()} ');
这是一个JSFiddle。
扩充内置库可能会导致与其他库的冲突(有些见),所以你可能更喜欢直接将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 );
我喜欢Linus的reduce()方法,特别是对于大型数组。但只要你知道你需要最小值和最大值,为什么要迭代数组两次呢?
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];
};
如果你有一个复杂的对象,你可以使用排序....例如:如果我想获得包含MAX/MIN值低于objs的项目。
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. obs]length-1]是最大值。
博士tl;
// 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解决方案
关于Math.max()的官方MDN文档已经涵盖了这个问题:
下面的函数使用function .prototype.apply()来查找数值数组中的最大元素。getMaxOfArray([1,2,3])等价于Math。max(1,2,3),但是您可以在任何大小的编程构造数组上使用getMaxOfArray()。 函数getMaxOfArray(numArray) { Math.max返回。应用(null, numArray); } 或者使用新的展开运算符,获得数组的最大值变得容易得多。 Var arr = [1,2,3]; var max = Math.max(…arr);
数组的最大大小
根据MDN, apply和spread解决方案的限制为65536,这来自于参数的最大数量的限制:
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.
他们甚至提供了一种混合解决方案,与其他解决方案相比,它的性能并不好。有关更多信息,请参阅下面的性能测试。
2019年的实际限制是调用堆栈的最大大小。对于现代基于Chromium的桌面浏览器,这意味着当使用apply或spread来查找min/max时,实际上只有数字的数组的最大大小是~120000。在此之上,将会出现堆栈溢出,并抛出以下错误:
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)); 尝试{ Math.max。应用(null, testArray); } catch (e) { console.log(我); 打破; } }
大型阵列的性能
基于EscapeNetscape评论中的测试,我创建了一些基准测试,在一个只有100000项的随机数数组上测试5种不同的方法。
2019年的结果显示,标准循环(BTW没有大小限制)在任何地方都是最快的。apply和spread紧随其后,然后是MDN的混合解决方案,然后reduce是最慢的。
几乎所有的测试都给出了相同的结果,除了其中一个扩散somewhy的结果是最慢的。
如果你将你的数组增加到100万个项目,事情就会开始中断,你只剩下标准循环作为快速解决方案,而减少作为较慢的解决方案。
JSPerf基准
JSBen基准
JSBench。我的基准
基准测试源代码
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);