使用JavaScript中的reduce函数查找数组中的最小和最大数字

10

只是出于好奇。使用reduce函数,我们可以轻松地分别在数组中找到最小值和最大值。就像这样:

var a = [1,2,3,4,5,1,-1,6,7,8,9,10,2,11];
a.reduce(function(prev,cur,index,array){
    return prev > cur ? prev : cur;
}); // returns 11

a.reduce(function(prev,cur,index,array){
    return prev < cur ? prev : cur;
}); // returns -1

鉴于这一点,为什么这不起作用呢?

var a = [1,2,3,4,5,1,-1,6,7,8,9,10,2,11];
var smallest = 0;
var biggest = 0;
a.reduce(function(prev,cur,index,array){
    smallest = prev < cur ? prev : cur;
    biggest =  prev > cur ? prev : cur;
});
console.log([smallest, biggest]); // prints [11,11]

在repl.it上进行了测试。

4个回答

7
在下面:
a.reduce(function(prev,cur,index,array){
    smallest = prev < cur ? prev : cur;
    biggest =  prev > cur ? prev : cur;
});
< p >传递给reduce的函数没有返回语句,因此它返回undefined。所以在第一次迭代后,prev被设置为undefined

如果抽象关系比较算法中的任一表达式未定义,则表达式返回undefined(参见步骤3.c),这将评估为false。因此从第二次迭代开始,smallestbiggest都设置为cur,最后它们都设置为数组中的最后一个值。


谢谢您的回答。当我添加了一个带有“smallest”变量的返回语句时,所有事情都正常了。虽然@zerkms的答案完美运行(我已经测试过,并且我也想给它点赞,但在我做这件事之前就被删除了),但是您指出了问题所在。 - cezarlamann

3
在使用 reduce 函数时,你需要在函数内部返回某些值,否则 reduce 会忘记之前的值。

var a = [1,2,3,4,5,1,-1,6,7,8,9,10,2,11];
var initial = {
  smallest: a[0],
  biggest: a[0]
};
var result = a.reduce((prev, cur) => {
  prev.smallest = prev.smallest < cur ? prev.smallest : cur;
  prev.biggest = prev.biggest > cur ? prev.biggest : cur;
  return prev;
}, initial);

console.log(result);
// Prints object as,
// { smallest: -1, biggest: 11 }


要进一步完善这一点,如果你只想要一个数组中的最大或最小值(并且从一个对象数组中获取),可以像这样进行调整:a = [{x: 1}, {x: 2}, {x: 3}]; a.reduce((previous, current) => previous > current.x ? previous : current.x, 0); - undefined

2

有两个问题。

首先,reduce 的 lambda 参数没有返回值。如果你不打算返回任何东西,那么 reduce 就只是带有更多没用参数的 forEach

其次,在每个元素上,你将curprev进行比较,而不是将其与biggestsmallest进行比较。


2
我知道这很古老,但是以下是如何使用数组 reduce 解决此类问题的方法:
var a = [1,2,3,4,5,1,-1,6,7,8,9,10,2,11];

var minNumber = a.reduce(function(prev,cur) {
    return prev < cur ? prev : cur;
}, +Infinity);

var maxNumber = a.reduce(function(prev,cur) {
    return prev > cur ? prev : cur;
}, -Infinity);

个人建议直接使用 Math.min/max

var a = [1,2,3,4,5,1,-1,6,7,8,9,10,2,11];

Math.min(...a) // will give -1
Math.max(...a) // will give 11

1
maxNumber 应该被初始化为 -Infinity,而不是其他值。 - marmor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接