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

JavaScript函数式实现数组非递减:元素小于前值时取前值

需求说明
  • 存在包含数值下降片段的数组,需要处理为全程无递减的非递减数组
  • 测试原数组:
const numbers = [0,1,2,3,4,5,1, 2];
  • 期望输出结果:
[0, 1, 2, 3, 4, 5, 5, 5]
现有实现问题

可正常运行的for循环实现

for循环可以直接修改原数组,遍历过程中读取的是已经修改过的前一个元素,因此可以得到正确结果:

for (let index = 0; index < numbers.length; index++) {
    const element = numbers[index];
    if (index > 0) {
      const prevEl = numbers[index - 1];
      if (element < prevEl) {
        numbers[index] = prevEl;
      }
    }
}

map实现的错误版本

尝试直接用Array.map实现时,得到的结果不符合预期:

const numbers = [0,1,2,3,4,5,1, 2];

const result = numbers.map((item, index) => {
    const prevEl = numbers[index - 1];
    if (item < prevEl) {
        return prevEl;
      }
    return item;
});

console.log(result); // 输出 [0, 1, 2, 3, 4, 5, 5, 2]

错误原因

Array.map 遍历过程中始终读取原数组的元素,不会引用回调之前返回的修改值:处理最后一个元素2时,读取的原数组索引6位置的值还是1,判定2>1就直接返回了原数值2,因此结果错误。

函数式编程正确实现

这个需求本质是计算数组截至每个位置的累计最大值,最适合用Array.reduce实现,不需要修改原数组,也没有外部状态,符合纯函数式要求:

const numbers = [0,1,2,3,4,5,1,2];
const result = numbers.reduce((acc, cur) => {
  // 取前一个处理完成的值,首个元素直接取当前值
  const lastVal = acc.at(-1) ?? cur;
  acc.push(Math.max(lastVal, cur));
  return acc;
}, []);

console.log(result); // 输出 [0,1,2,3,4,5,5,5]

如果一定要用map实现,需要额外维护一个变量记录累计最大值,但这种写法依赖外部可变状态,不属于纯函数式范式:

const numbers = [0,1,2,3,4,5,1,2];
let currentMax = -Infinity;
const result = numbers.map(item => {
  currentMax = Math.max(currentMax, item);
  return currentMax;
});

内容的提问来源于stack exchange,提问作者Shiny Diamond

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:36:23