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

为何JS代码中filter会移除所有最小元素?原需求仅移除一个

问题:移除数组第一个最小元素时的逻辑错误分析

我需要从数组中仅移除第一个出现的最小元素(即使存在多个相同的最小值),但下面的代码却移除了所有最小元素。我有个疑问:minNum明明是第一个最小元素1的索引2,为什么filter会把第二个1也移除?

原问题代码

const arr = [6, 3, 1, 4, 1];

const removeSmallestNum = function(arr) {
    const copy = arr.slice();
    const minNum = copy.indexOf(Math.min(...copy));
    console.log(minNum);
    return copy.filter(num => copy.indexOf(num) !== minNum);
}

const result = removeSmallestNum(arr);
console.log(result)

代码执行逻辑拆解

我们一步步拆解这段代码的运行过程:

  1. const copy = arr.slice(); 复制原数组,此时copy的值为[6, 3, 1, 4, 1]。
  2. Math.min(...copy)计算出数组最小值是1,接着copy.indexOf(1)找到第一个1的索引2,所以minNum = 2。
  3. 关键问题出在filter的回调函数:num => copy.indexOf(num) !== minNum
    • 遍历数组每个元素时,copy.indexOf(num)始终返回第一个匹配元素的索引:
      • 遍历到第一个1时,copy.indexOf(1)是2,等于minNum,所以被过滤掉;
      • 遍历到第二个1时,copy.indexOf(1)还是2(因为indexOf只找第一个出现的1),同样等于minNum,所以也被过滤掉;
      • 其他元素的indexOf结果都不等于2,因此被保留。
    • 最终两个1都被移除,得到结果[6, 3, 4],不符合需求。

正确实现方式(使用splice)

CodeWars上的正确写法是用splice替代filter,splice可以精准删除指定索引的单个元素:

const removeSmallestNum = function(arr) {
    const copy = arr.slice();
    const minIndex = copy.indexOf(Math.min(...copy));
    copy.splice(minIndex, 1); // 从索引minIndex的位置删除1个元素
    return copy;
}

注意:如果直接return copy.splice(minIndex, 1),返回的是被删除的元素(即[1]),而不是修改后的数组。需要先执行splice修改数组,再返回copy才能得到移除第一个最小元素后的数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:32:16