JavaScript 专题之如何求数组的最大值和最小值
取出数组中的最大值或者最小值是开发中常见的需求,但你能想出几种方法来实现这个需求呢?
Math.max
JavaScript 提供了 Math.max 函数返回一组数中的最大值,用法是:
Math.max([value1[,value2, ...]])
值得注意的是:
- 如果有任一参数不能被转换为数值,则结果为 NaN。
- max 是 Math 的静态方法,所以应该像这样使用:Math.max(),而不是作为 Math 实例的方法 (简单的来说,就是不使用 new )
- 如果没有参数,则结果为
-Infinity
(注意是负无穷大)
而我们需要分析的是:
1.如果任一参数不能被转换为数值,这就意味着如果参数可以被转换成数字,就是可以进行比较的,比如:
Math.max(true, 0) // 1 Math.max(true, '2', null) // 2 Math.max(1, undefined) // NaN Math.max(1, {}) // NaN
2.如果没有参数,则结果为 -Infinity,对应的,Math.min 函数,如果没有参数,则结果为 Infinity,所以:
var min = Math.min(); var max = Math.max(); console.log(min > max);
了解了 Math.max 方法,我们以求数组最大值的为例,思考有哪些方法可以实现这个需求。
原始方法
最最原始的方法,莫过于循环遍历一遍:
var arr = [6, 4, 1, 8, 2, 11, 23]; var result = arr[0]; for (var i = 1; i < arr.length; i++) { result = Math.max(result, arr[i]); } console.log(result);
reduce
既然是通过遍历数组求出一个最终值,那么我们就可以使用 reduce 方法:
var arr = [6, 4, 1, 8, 2, 11, 23]; function max(prev, next) { return Math.max(prev, next); } console.log(arr.reduce(max));
排序
如果我们先对数组进行一次排序,那么最大值就是最后一个值:
var arr = [6, 4, 1, 8, 2, 11, 23]; arr.sort(function(a,b){return a - b;}); console.log(arr[arr.length - 1])
eval
Math.max 支持传多个参数来进行比较,那么我们如何将一个数组转换成参数传进 Math.max 函数呢?eval 便是一种
var arr = [6, 4, 1, 8, 2, 11, 23]; var max = eval("Math.max(" + arr + ")"); console.log(max)
apply
使用 apply 是另一种。
var arr = [6, 4, 1, 8, 2, 11, 23]; console.log(Math.max.apply(null, arr))
ES6 ...
使用 ES6 的扩展运算符:
var arr = [6, 4, 1, 8, 2, 11, 23]; console.log(Math.max(...arr))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: JavaScript 专题之数组扁平化
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
Math.max.apply(null, arr)
,用对象null调用参数为arr的max方法,这原理为什么能成功?ES6中也可以用Reflect的方式实现求数组的最大值和最小值
例:var arr = = [1,2,7,9,3,4,5];
Relfect.apply(Math.max,Math,arr) // 9
Reflect.apply(Math.min,Math,arr) //1
@MoYummy
apply()
方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。简单来说第一个参数就是改变原函数运行时的
this
值。一些原型上的方法作用的对象是其
this
值。比如使用
Array.prototype.slice.apply(arguments)
将arguments
对象转换为数组。但
max()
是Math
的静态方法,调用时方法内this
值对结果没有影响。@mqyqingfeng 楼主好,这也算一种最简单的方法吧,并且有{}或者undefined也能正常运行,function sortArr(arr) {
var max = min = arr[0];
for (var i = 0; i < arr.length; i++) {
arr[i] > max ? max = arr[i] : '';
arr[i] < min ? min = arr[i] : '';
}
return [max, min]
}
console.log(sortArr([11, 3, 5, 3, 66, 22, 66, 33, 565, 2222, 4, 3,{},]))
用reduce,求最大最小有点小风险,当arr为空数组时,代码运行会报错
所以,运行前最好做个判断
var arr = [ ];
function max(prev, next) {
return Math.max(prev, next);
}
console.log(arr.reduce(max));
@Tan90Qian 好思路,都没有注意到这一点~ (๑•̀ㅂ•́)و✧
@Panzhipeng1 好方法,感谢补充哈~
@Panzhipeng1 如果传入一组正确的参数给Math.max方法,返回的结果都是"number"类型的,而你这个并没有进行类型转化,两者的结果并不一致。当然这得看实际的需求需不需要进行类型转化,以及“最大”和“最小”是依据什么来判断的。
@crowphy 哈哈,这个用的是 MDN 的写法,这个方括号是用来表示该参数非必填,可以传也可以不传……如果不用 [] 的话,我不知道对于非必填参数怎么描述了……
JavaScript 提供了 Math.max 函数返回一组数中的最大值,用法是:
Math.max([value1[,value2, ...]])
这样写容易让人以为传入的是个数组,比如我。。。
哈哈哈懂了,谢谢两位的回答~
@sinkinlife 感谢回答哈~ ( ̄▽ ̄)~*
@MillionQW 这是因为发生了隐式类型转换,举个简单例子:
其实
其实就相当于
@MillionQW 因为数组被转换成字符串了啊。。。
你好,可以请教一下eval求数组最大值的原理是什么吗?已知给eval()传入字符串,如果字符串是表达式的话就会被执行,但是不明白为什么把Math.max( 和右括号转出字符串中间夹个数组就能求出最大值。
@jiangshanmeta 嗯好,四个系列完结后,我会重新修订这些内容,到时候一定补充上这些内容~
还以为要从头实现一个underscore的_.max _.min呢
@shixuev5 感谢回答哈~
@zhqgit 扩展运算符(...)可以将一个数组变为参数序列,引用阮一峰老师的《ECMAScript 6 入门》
@zhqgit var arr = [6, 4, 1, 8, 2, 11, 23];
console.log(...arr ) // 6 4 1 8 2 11 23