You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算数组中两个有效数值间的零值并实现线性填充?

线性填充数组中的0值(基于前后有效数值插值)

需求:给定一个包含0值的数值数组,需要用相邻两个有效数值之间的线性差值填充所有0值。示例数组 arr = [10,0,0,16,17,0,23],期望输出 [10,12,14,16,17,20,23]。

以下是我当前的JavaScript实现代码,但无法得到正确结果,寻求可行解决方案:

let arr = [10,0,0,16,17,0,23]
//required result [10,12,14,16,17,20,23]
// here is my code

const getValueIf = (item, index, array) => {
  const lastindex = array.length - 1;
  const zeroWithFirst = index !== 0 && item === 0;
  const zeroWithLast = index !== lastindex && item === 0;
  const firstZero = index === 0 && item === 0;
  if (firstZero) {
    return array[index] = ifZeroToNumber(array, index) ;
  }
  if (zeroWithFirst || zeroWithLast) {
    if (zeroWithFirst && !zeroWithLast) {
      return array[index - 1];
    }
    if (!zeroWithFirst && zeroWithLast) {
      return array[index + 1] === 0 ? array[index + 2] : array[index + 1];
    }
    array[index] =
      (ifZeroToNumber(array, index) - array[index - 1]) / 2 +
      array[index - 1];
    return (
      (ifZeroToNumber(array, index) - array[index - 1]) / 2 + array[index - 1]
    );
  } else {
    return item;
  }
};

const ifZeroToNumber = (array, index) => {
  let num = 0;
  for (let i = 1; i <= array.length; i++) {
    if (num === 0 && array[index + i]) {
      num = array[index + i];
    }
  }
  if (!num) {
    num = array[index - 1];
  }
  return num;
};
let removeZero = arr.map((value, index) =>
    getValueIf(value, index, arr)
  );
console.log(removeZero)

现有代码的问题

  • 只处理了间隔1个0的场景,遇到多个连续0(比如示例里的前两个0)时计算逻辑失效
  • ifZeroToNumber 函数无法正确定位后续的有效数值,当连续多个0时会出错
  • 插值逻辑简单粗暴,没有根据两个有效数之间的间隔数量计算正确的步长
  • 使用map时直接修改原数组,可能干扰后续的遍历计算

可行实现方案

核心思路是先找出所有非0的"锚点"(记录索引和对应值),再对每一对相邻锚点之间的0值做线性插值计算:

const linearFillZeros = (arr) => {
  // 收集所有非0的锚点
  const anchors = arr.reduce((acc, val, idx) => {
    if (val !== 0) acc.push({ idx, val });
    return acc;
  }, []);

  // 边界情况处理:没有锚点直接返回原数组,单个锚点则全填充该值
  if (anchors.length === 0) return [...arr];
  if (anchors.length === 1) return arr.map(() => anchors[0].val);

  const result = [...arr];

  // 遍历每对相邻锚点,填充中间的0
  for (let i = 0; i < anchors.length - 1; i++) {
    const start = anchors[i];
    const end = anchors[i + 1];
    // 计算步长:总差值除以间隔步数(比如10到16之间有2个0,步数是3)
    const step = (end.val - start.val) / (end.idx - start.idx);

    // 逐个填充中间的0
    for (let j = start.idx + 1; j < end.idx; j++) {
      result[j] = start.val + step * (j - start.idx);
      // 如果需要整数结果,可改为:Math.round(start.val + step * (j - start.idx))
    }
  }

  // 处理数组开头的连续0
  if (anchors[0].idx > 0) {
    const firstVal = anchors[0].val;
    for (let j = 0; j < anchors[0].idx; j++) {
      result[j] = firstVal;
    }
  }

  // 处理数组结尾的连续0
  if (anchors[anchors.length - 1].idx < arr.length - 1) {
    const lastVal = anchors[anchors.length - 1].val;
    for (let j = anchors[anchors.length - 1].idx + 1; j < arr.length; j++) {
      result[j] = lastVal;
    }
  }

  return result;
};

// 测试示例
const arr = [10,0,0,16,17,0,23];
console.log(linearFillZeros(arr)); // 输出: [10, 12, 14, 16, 17, 20, 23]

实现说明

  • 锚点收集确保能精准定位每一段需要插值的区间
  • 步长计算根据两个有效数之间的间隔动态调整,适配任意数量的连续0
  • 首尾的连续0会填充最近的有效数值,覆盖所有边界场景
  • 不修改原数组,返回新的填充后数组,避免副作用

内容的提问来源于stack exchange,提问作者Ali Nawaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 10:40:35