为什么在JavaScript中用两次reduce实现数组第二大数查找时返回NaN?
两次reduce()求数组第二大数返回NaN的原因分析
你的思路是先用reduce()找到数组最大值,再用第二次reduce()过滤掉最大值后找出剩余元素的最大值,但代码运行后secondBiggest返回NaN,核心问题有两个:
1. 回调函数未覆盖所有分支,隐式返回undefined
reduce()的回调函数必须在所有场景下都返回一个值,否则当不满足if(a!= biggest && b!= biggest)条件时,函数会隐式返回undefined,直接破坏后续迭代逻辑:
- 比如迭代到元素
9(也就是你找到的biggest)时,b === biggest导致if条件不成立,回调返回undefined,此时累加器a就变成了undefined - 后续迭代中,
Math.max(undefined, 5)、Math.max(undefined, 8)这类计算都会返回NaN,最终结果自然是NaN
2. 未指定reduce()初始值,存在边界风险
如果不给reduce()指定初始值,它会默认用数组第一个元素作为初始累加器a。如果数组第一个元素恰好是最大值,那第一次迭代时a === biggest,if条件不成立直接返回undefined,后续所有迭代都会基于undefined计算,直接得到NaN。
修正后的示例代码
只要让回调函数覆盖所有场景,同时指定初始值规避边界问题,就能得到正确结果:
const arr = [1,6,2,7,3,9,5,8]; const biggest = arr.reduce((a,b) => Math.max(a,b)); const secondBiggest = arr.reduce((a, b) => { // 当前元素是最大值,保留之前的累加值 if (b === biggest) return a; // 累加值是最大值,替换为当前元素 if (a === biggest) return b; // 都不是最大值,取两者较大值 return Math.max(a, b); }, arr[0]); // 指定初始值为数组第一个元素 console.log(secondBiggest); // 输出 8
内容的提问来源于stack exchange,提问作者Julio Rodriguez
相关产品推荐
相关产品推荐

