简单的减少功能 - JavaScript

时间:2017-07-25 04:36:08

标签: javascript ecmascript-6 reduce

我正在使用超级简单数据集上的cs-server@csserver-HP-EliteDesk-800-G2-SFF:/$ echo $ps_aux | grep "\-name" | sed -e "s/.*-name //g" | cut -f1 -d' ' i_want_this_string cs-server@csserver-HP-EliteDesk-800-G2-SFF:/$ 函数,并且当我没有预料到时,我得到了reduce:<\ n / p>

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。

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

2 个答案:

答案 0 :(得分:7)

这一切都与累加器(high)中的内容有关。如果你没有向reduce提供第二个参数,则累加器作为第一个对象开始,当前元素是第二个元素。在第一次迭代中,您将累加器视为对象,使用high.grade获取等级;但是你返回一个数字(94),而不是一个对象,作为你的下一个累加器。在循环的下一次迭代中,high不再是对象,而是94,而(94).grade没有任何意义。

删除第三个元素时,没有第二次迭代,并且没有时间发生错误,并且您获得当前累加器的值(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}结尾。

答案 1 :(得分:2)

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

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