简单的 Reduce 函数 - JavaScript

Simple Reduce Function - JavaScript

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


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

这一切都与累加器 (high) 中的内容有关。如果您不向 reduce 提供第二个参数,累加器将作为第一个对象开始,而当前元素是第二个元素。在您的第一次迭代中,您将累加器视为对象,使用 high.grade 获取成绩;但是你 return 一个数字 (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
)

此变体将累加器保留为数字,并将 return 94。我们不能依赖默认的起始累加器,因为它需要是一个数字,所以我们人为地将它设置为 -INF.

let highest = students.reduce(
    (high, current) => high.grade > current.grade ? high : current,
)

这是对象版本,其中 highest{name: 'Leah', grade: 94} 结束。

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

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