JavaScript中Array Reduce首次求和正确后返回NaN的原因排查
解决Array.reduce生成前缀和数组时出现NaN的问题
我来帮你理清这个问题——你遇到的NaN,本质是reduce回调的返回值类型在迭代过程中变了,导致后续的累加操作无法正常进行。
问题原因分析
从你给出的结果[1,3,NaN,NaN]反推,你的代码大概率是踩了这个坑:
- 第一次迭代:
total是数组的第一个元素1,和currentValue=2相加得到3,此时你可能把1和3组成数组返回; - 第二次迭代:
total变成了这个数组[1,3],当你尝试用它和currentValue=6做加法时,数组加数字会直接得到NaN,后续迭代自然也都是NaN了。
简单说:reduce要求每次回调的返回值,必须作为下一次迭代的total。如果第一次返回数字、第二次返回数组,后续的total类型混乱,累加逻辑自然崩了。
正确的实现方式
要生成前缀和数组,正确的做法是用数组作为reduce的初始值,每次迭代计算当前的累加值,再把它添加到数组里返回:
const numbers = [1, 2, 6, 4]; const prefixSums = numbers.reduce((acc, current) => { // 计算当前累加值:数组为空时直接用current,否则取最后一个元素加current const sum = acc.length === 0 ? current : acc[acc.length - 1] + current; // 返回新数组(保持纯函数特性,也可以直接push后返回acc) return [...acc, sum]; }, []); // 一定要设置初始值为空数组! console.log(prefixSums); // 输出 [1, 3, 9, 13]
为什么要设置初始值?
如果不设置初始值,reduce会把数组第一个元素作为初始的acc,从第二个元素开始迭代。这种情况下很容易出现返回值类型混乱的问题。设置初始值为空数组后,每一次迭代的acc都是数组,逻辑会清晰很多。
另一种简洁写法
如果你不在意操作数组副本,也可以直接在累加数组上push:
const numbers = [1, 2, 6, 4]; const prefixSums = numbers.reduce((acc, current) => { acc.push(acc.length ? acc[acc.length - 1] + current : current); return acc; }, []);
这样就能稳定生成你想要的前缀和数组啦~
内容的提问来源于stack exchange,提问作者user3869231
相关产品推荐
相关产品推荐

