如何修正滚动简单移动平均(SMA)计算代码以避免输出数组中的日期重复?
如何修正滚动简单移动平均(SMA)计算代码以避免输出数组中的日期重复?
嘿,我来帮你搞定这个问题~ 你遇到的日期重复问题,根源在于代码里的两个循环重复处理了第5天的数据:
你看,第一个for循环直接往结果数组里塞了**period个(也就是5个)**带null值的条目,把第5天(索引4)的日期也当成空值项加进去了;紧接着第二个循环又从i = period - 1(也就是索引4,对应第5天)开始计算SMA,再次把这个日期的计算结果塞进数组,这不就重复了嘛!
给你两种修正方案,选哪个都行:
方案一:调整第一个循环的次数
直接把第一个循环的终止条件改成i < period - 1,这样只往结果里加前period-1个(也就是4个)空值项,第二个循环再正常从第5天开始添加计算好的SMA值,就不会重复了:
function calcAverage(data, period) { let result = []; period = period || 5; // 只添加前period-1个空值项,避免重复处理第period天 for (let i = 0; i < period - 1; i++) result.push({ x: data[i].x, y: null }); for (let i = period - 1; i < data.length; i++) { let window = data.slice(i - period + 1, i + 1); let mean = window.reduce((sum, val) => sum + val.y[3], 0) / period; if (isNaN(mean)) result.push({ x: data[i].x, y: null }); else result.push({ x: data[i].x, y: mean }); } return result; }
方案二:合并循环,更简洁
把两个循环合并成一个,遍历所有数据项,根据索引判断是加空值还是计算SMA,逻辑更清晰:
function calcAverage(data, period) { let result = []; period = period || 5; for (let i = 0; i < data.length; i++) { if (i < period - 1) { // 前period-1天没有足够数据计算SMA,直接存null result.push({ x: data[i].x, y: null }); } else { // 从第period天开始,取最近period天的收盘价计算平均值 let window = data.slice(i - period + 1, i + 1); let mean = window.reduce((sum, val) => sum + val.y[3], 0) / period; // 处理可能的NaN情况 result.push({ x: data[i].x, y: isNaN(mean) ? null : mean }); } } return result; }
这样修改后,输出数组里的第5天就只会出现一次,就是带计算好的SMA值的那个条目,前4天都是null,完全符合你的预期啦~
备注:内容来源于stack exchange,提问作者fitted_sheet
相关产品推荐
相关产品推荐

