简单Reduce函数-JavaScript
我在一个超级简单的数据集上使用简单Reduce函数-JavaScript,javascript,ecmascript-6,reduce,Javascript,Ecmascript 6,Reduce,我在一个超级简单的数据集上使用reduce函数,我得到了NaN,结果出乎意料: let students = [{name: 'Leah', grade: 94},{name: 'Savannah', grade: 73},{name: 'Killian', grade: 38}]; let highest = students.reduce( (high, current) => Math.max(high.grade, current.grade) ) consol
reduce
函数,我得到了NaN
,结果出乎意料:
let students = [{name: 'Leah', grade: 94},{name: 'Savannah', grade: 73},{name: 'Killian', grade: 38}];
let highest = students.reduce(
(high, current) => Math.max(high.grade, current.grade)
)
console.log(highest); // outputs NaN
奇怪的是,如果我将第一行更改为以下内容:(只需取出第三个对象)
然后它正确运行并输出94
为什么添加一个额外的对象会导致问题?这一切都与累加器中的内容有关(
高
)。如果不向reduce
提供第二个参数,累加器将作为第一个对象启动,当前元素是第二个元素。在第一次迭代中,将累加器视为对象,使用high.grade
获取等级;然后返回一个数字(94
),而不是一个对象,作为下一个累加器。在循环的下一次迭代中,high
不再是一个对象,而是94
,和(94)。grade
没有意义
当您删除第三个元素时,没有第二次迭代,也没有时间让bug发生,您将获得当前累加器的值(94
)。如果只有一个元素,您将获得初始累加器({name:'Leah',grade:94}
)。显然,这并不理想,因为您无法可靠地预测计算结果的形状(对象、数字或错误)
您需要决定是要数字还是对象,一个还是另一个
let highest = students.reduce(
(high, current) => Math.max(high, current.grade),
Number.NEGATIVE_INFINITY
)
此变量将累加器保留为一个数字,并将返回94
。我们不能依赖默认的起始累加器,因为它需要是一个数字,所以我们人为地将它设置为-INF
let highest = students.reduce(
(high, current) => high.grade > current.grade ? high : current,
)
这是对象版本,其中
highest
以{name:'Leah',grade:94}
结束。这里的问题是,第一次传递后的累加器(high)是一个数字(math.max返回的值),但每次传递都要求high是一个对象,grade是一个数字属性。因此,在第二次调用时,您正在调用Math.max(未定义,73)
——它将返回NaN
。相反,我建议使用-Infinity
初始化累加器,并且只提供高值
:
let highest=students.reduce(
(高,当前)=>数学最大值(高,当前,等级)
,-Infinity)
使用调试器逐步完成代码。每次通过循环,检查高
和当前
的值。你应该很快就能解决这个问题。谢谢你,你应该看到的。如果再添加一个对象,这个例子实际上会失败,我这样说对吗?(描述标题下的第一个示例)是的,如果添加另一个对象,它将返回NaN。您可以在控制台中轻松地进行测试以进行验证。@qarthandso对于描述下面的第一个示例,他们说您应该使用.map
和初始值,而不是不带initialValue的reduce()
示例。但他们也应该包括三个对象的失败案例;我相信这个例子正是为了警告这种情况(如果没有初始值,您需要非常小心,因为可能会出现几种不同的情况)。这个例子和你的完全一样。如果不指定初始值,则回调返回值的类型需要与第一个元素的类型匹配,否则会出现混乱。
let highest = students.reduce(
(high, current) => high.grade > current.grade ? high : current,
)