sumAll函数参数顺序颠倒触发空数组Reduce报错,求解决方法
sumAll函数参数顺序导致的测试失败问题及修复
问题情况
运行npm test时,6个测试用例里的第3个未通过——调用sumAll(123, 1)时抛出错误:Reduce of empty array with no initial value。试过对函数做排序处理、加条件判断、给reduce设初始值0,都没解决,需要让函数在第一个参数大于第二个参数时也能正常计算区间和。
用户尝试的无效排序代码
sumAll.sort(function(min,max)) { return max - min; }
原sumAll函数代码
const sumAll = function( min, max ) { let fullArr = []; let sum = 0; const reducer = (accumulator, currentValue) => accumulator + currentValue; for ( let i = min; i <= max; i++) { fullArr.push(i); } sum = fullArr.reduce(reducer); return sum; } sumAll(1,4); sumAll(123, 1); // 此处调用报错'Reduce of empty array with no initial value....
Jest测试代码
const sumAll = require('./sumAll') describe('sumAll', () => { test('sums numbers within the range', () => { expect(sumAll(1, 4)).toEqual(10); }); test('works with large numbers', () => { expect(sumAll(1, 4000)).toEqual(8002000); }); test('works with larger number first', () => { expect(sumAll(123, 1)).toEqual(7626); }); test.skip('returns ERROR with negative numbers', () => { expect(sumAll(-10, 4)).toEqual('ERROR'); }); test.skip('returns ERROR with non-number parameters', () => { expect(sumAll(10, "90")).toEqual('ERROR'); }); test.skip('returns ERROR with non-number parameters', () => { expect(sumAll(10, [90, 1])).toEqual('ERROR'); }); });
问题根源
当调用sumAll(123, 1)时,min=123、max=1,for循环的条件i <= max一开始就不成立,导致fullArr是空数组。而reduce方法在处理空数组且没有初始值时,必然会抛出那个错误。
之前尝试的排序代码无效,是因为sort是数组的方法,直接对sumAll函数调用sort完全错误,函数本身没有这个方法。
修复方案
方案1:先修正参数顺序(简单直观)
在函数开头判断两个参数的大小,若第一个参数更大,就交换两者的值,确保循环能正常生成区间内的所有数:
const sumAll = function(min, max) { // 确保min是较小值,max是较大值 if (min > max) { [min, max] = [max, min]; } let fullArr = []; const reducer = (accumulator, currentValue) => accumulator + currentValue; for (let i = min; i <= max; i++) { fullArr.push(i); } return fullArr.reduce(reducer, 0); // 给reduce加初始值0,避免极端情况(比如参数相等时)的空数组问题 }
方案2:根据参数顺序调整循环逻辑
不交换参数,而是根据参数大小选择循环的方向:
const sumAll = function(min, max) { let fullArr = []; const reducer = (accumulator, currentValue) => accumulator + currentValue; if (min <= max) { for (let i = min; i <= max; i++) { fullArr.push(i); } } else { for (let i = min; i >= max; i--) { fullArr.push(i); } } return fullArr.reduce(reducer, 0); }
方案3:用数学公式直接计算(高效最优)
其实不需要生成数组,用等差数列求和公式直接计算区间和,效率更高,代码也更简洁:
const sumAll = function(min, max) { const small = Math.min(min, max); const big = Math.max(min, max); // 公式:(首项 + 末项) × 项数 ÷ 2 return (small + big) * (big - small + 1) / 2; }
验证结果
修复后运行npm test,第3个测试用例sumAll(123,1)会返回7626,和测试预期一致,其他测试用例也能正常通过。
内容的提问来源于stack exchange,提问作者Jabri Juhinin
相关产品推荐
相关产品推荐

