
本文介绍如何在 react native 中为数组中每个位置计算“截至当前索引(不含首项)的累积平均值”,即第 i 项对应前 i 个 volume 值(索引 0 到 i−1)的平均值,适用于动态展示传感器读数趋势等场景。
在 React Native 开发中,常需对时间序列数据(如传感器读数)进行实时统计处理。题中需求并非简单数组均值,而是一种前缀累积平均(running average excluding self):对于长度为 n 的 readings 数组,目标是生成一个新数组 averages,其中:
- averages[0] 对应空或占位值(因无前置元素),通常设为 0 或 null;
- averages[1] = (readings[0].volume + readings[1].volume) / 1 → 实际是前 2 个值之和除以 1(注意:题中“除以 1”对应区间长度减 1,本质是前 i 项和 ÷ (i − 0)?但结合示例 3,5,6,9 推导可知:题意实为——第 i 个结果 = 前 i 个元素(索引 0 至 i−1)的 volume 总和 ÷ (i − 1),仅当 i ≥ 1;然而答案代码与示例逻辑更统一:averages[i] = (sum of volumes[0..i−1]) / i(i ≥ 1),即:
| 索引 i | readings[i] | averages[i](定义) | 计算过程 |
|---|---|---|---|
| 0 | {volume: 3} | 0(或跳过) | — |
| 1 | {volume: 5} | (3) / 1 = 3 | 前 1 项(索引0) |
| 2 | {volume: 6} | (3+5) / 2 = 4 | 前 2 项(索引0-1) |
| 3 | {volume: 9} | (3+5+6) / 3 = 4.67 | 前 3 项(索引0-2) |
✅ 这正是答案函数 runningVolumeAverage 所实现的逻辑:逐项累加 volume,并在每次迭代时,用当前累计和除以当前索引 i(即已处理的前置元素个数)。
以下是推荐的生产就绪实现:
// 工具函数:生成累积平均数组(索引0处为undefined/0,索引i≥1处为前i项平均)
function runningVolumeAverage(arr) {
let sum = 0;
return arr.map(({ volume }, i) => {
sum += volume;
// i === 0 时,尚未有“前置平均”概念,返回 0 或 null;此处按题设返回 0
return i === 0 ? 0 : sum / i;
});
}
// 在组件中使用
const averages = runningVolumeAverage(readings);
return (
{readings.map(({ id, date, volume }, i) => (
average: {averages[i]?.toFixed(2) ?? '—'}
))}
);⚠️ 关键注意事项:
- 不要在 map 内部重复计算:原问题中尝试在每次渲染时循环计算,会导致 O(n²) 时间复杂度且逻辑错乱(如 i 变量未声明、覆盖问题)。务必预计算一次 averages 数组。
- 索引对齐:readings.map(..., i) 中的 i 是数组下标,与 averages[i] 严格对应,确保数据一致性。
-
空数组防护:若 readings 可能为空,建议增强函数鲁棒性:
function runningVolumeAverage(arr) { if (!Array.isArray(arr) || arr.length === 0) return []; let sum = 0; return arr.map(({ volume }, i) => { sum += volume; return i === 0 ? 0 : sum / i; }); } - 显示优化:使用 .toFixed(2) 控制小数位,避免 NaN 或 Infinity,配合空值 fallback(如 '—')提升 UI 健壮性。
该方案时间复杂度 O(n),简洁高效,符合 React 的不可变数据流原则,可直接集成至任意列表渲染逻辑中。










