JavaScript。使用 Splice() 方法过滤数组

JavaScript. Filtering an array with the Splice() method

我需要写一个函数

filterRangeInPlace(arr, a, b)

接受一个数组和两个数字,并删除数组中不在 ab 范围内的所有元素。所以支票看起来像

a ≤ arr[i] ≤ b

我想用for循环拼接的方式来做。但无法弄清楚为什么该函数将某些元素保留在范围之外,在我的例子中,它是 number 3。这不是家庭任务或其他什么,我只是在练习数组方法。这是我的代码:

let myArr = [1, 3,  8, 3, 9, 5, 3, 4, 10, 7, 6, 1]

function filterRangeInPlace( arr, a, b ) {
    for ( i = 0; i < arr.length; i++ ) {
        if ( arr[i] < a || arr[i] > b ) {
            arr.splice(i, 1)
        }
    }
}

filterRangeInPlace(myArr, 4, 9)

console.log(myArr) // [3, 8, 9, 5, 4, 7, 6]

我知道我在某处弄乱了索引,但无法弄清楚在哪里以及如何,因为其余的工作正常。谢谢!

当你使用splice时,你仍然在同一个循环中,你跳过了一些索引(因为拼接删除了一些项目,所以索引被改变了)。

在您的示例中,第一个 1 被删除,因此 3 成为第一个,然后您跳到第二个(循环中的 i++ ).您没有仔细检查相同的索引。

我建议使用 filter 方法来做到这一点,或者只是将 i-- 放在 splice 之后的行上。

如果您在此处使用 splice,则应从数组末尾开始迭代,直到第一个元素为:

for (i = arr.length - 1; i >= 0; i--) {

假设您要删除位置 0 处的第一个元素,即 1,然后删除数组后将是

[3, 8, 3, 9, 5, 3, 4, 10, 7, 6, 1]

然后 i 递增并变为 1,所以现在它将指向 8 作为 1 索引。

所以使用splice会跳过一些步骤

let myArr = [1, 3, 8, 3, 9, 5, 3, 4, 10, 7, 6, 1];

function filterRangeInPlace(arr, a, b) {
  for (i = arr.length - 1; i >= 0; i--) {
    if (arr[i] < a || arr[i] > b) {
      arr.splice(i, 1);
    }
  }
}

filterRangeInPlace(myArr, 4, 9);
console.log(myArr);