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