【问题标题】:Simple Reduce Function - JavaScript简单归约函数 - JavaScript
【发布时间】:2017-12-30 19:58:50
【问题描述】:

我在一个超级简单的数据集上使用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

奇怪的是,如果我将第一行更改为以下内容:(仅取出第三个对象)

let students = [{name: 'Leah', grade: 94},{name: 'Savannah', grade: 73}];

然后它运行正确并输出 94。


为什么添加一个额外的对象会导致问题?

【问题讨论】:

  • 使用调试器单步调试您的代码。每次循环时,检查highcurrent 的值。您应该能够很快找出问题所在。

标签: javascript ecmascript-6 reduce


【解决方案1】:

这一切都与累加器中的内容有关 (high)。如果您不向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} 结尾。

【讨论】:

  • 谢谢,应该已经看到了。我是否正确地说,如果再添​​加一个对象,mozilla page 上的示例实际上会失败? (描述标题下的第一个示例)
  • 是的,如果您添加另一个对象,它将返回 NaN。您可以在控制台中轻松测试以进行验证。
  • @qarthandso 对于描述下方的第一个示例,他们说您应该使用.map 和初始值而不是reduce() without initialValue 示例。但他们也应该包含三个对象的失败案例。
  • 确实;我相信这个例子正是为了警告这种情况(没有初始值,你需要非常小心,因为有几种不同的情况可以发挥作用)。该示例与您的示例完全相同。不指定初始值时,回调返回值的类型需要与第一个元素的类型匹配,否则会出现混乱。
【解决方案2】:

这里的问题是第一次传递后的累加器(高)是一个数字(由 math.max 返回),但每次传递都要求高是一个具有等级作为数字属性的对象。因此,在第二次调用时,您将调用 Math.max(undefined, 73) - 这将返回 NaN。相反,我建议使用-Infinity 初始化累加器,并且只提供high

let highest = students.reduce( (high, current) => Math.max(high, current.grade) , -Infinity)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 2015-05-27
    相关资源
    最近更新 更多