通过在 Javascript 中使用 splice 函数切割数组来编写基本算法脚本

Base Algorithm Scripting by chopping the array with splice function in Javascript

现在我正在 freecodecamp 做一个练习。目前我遇到了一个逻辑错误,但不知道失败的原因。

在代码中,我必须构建一个函数,该函数根据参数切分输入数组。测试结果应该如下:

chunkArrayInGroups(["a", "b", "c", "d"], 2) should return [["a", "b"], ["c", "d"]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5], 3) should return [[0, 1, 2], [3, 4, 5]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 4) should return [[0, 1, 2, 3], [4, 5, 6, 7], [8]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2) should return [[0, 1], [2, 3], [4, 5], [6, 7], [8]].

而我的代码如下:

function chunkArrayInGroups(arr, size) {
  var array = [];
  for (var x = 0; x < arr.length ; x+=size){
    var spliceArr = arr.splice(0,size);
    array.push(spliceArr);
  }
  array.push(arr);
  return array;
}

chunkArrayInGroups(["a", "b", "c", "d","e"], 2);

对于大多数情况,代码都有效。但对于最后一个条件,即

chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2) should return [[0, 1], [2, 3], [4, 5], [6, 7], [8]].

在这种情况下我无法得到正确答案。我在控制台日志中进行了测试,结果输出类似于

[[0, 1], [2, 3], [4, 5], [6, 7, 8]].

我知道这不是一个困难的问题并且有很多更好的方法来解决它,但是我能知道这段代码中的逻辑错误是什么吗? 非常感谢!

使用 slice 而不是 splice。这也将保证原始数组不被修改。

像这样(工作演示):

function chunkArrayInGroups(arr, size) {
  var array = [];
  for (var x = 0; x < arr.length; x += size) {
     // take elements from current index (`x`) to `x` + `size`
     // (do not remove them from the original array, so the original size is not modified either)
    var sliceArr = arr.slice(x, x + size);
    array.push(sliceArr);
  }
  return array;
}


console.log(chunkArrayInGroups(["a", "b", "c", "d"], 2)); //should return [["a", "b"], ["c", "d"]].
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5], 3)); // should return [[0, 1, 2], [3, 4, 5]].
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 4)); // should return [[0, 1, 2, 3], [4, 5, 6, 7], [8]].
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2)); // should return [[0, 1], [2, 3], [4, 5], [6, 7], [8]]

console.log(arr) 添加到循环中可能有助于查看数组随时间的变化情况。

你会看到它看起来像这样:

[0, 1, 2, 3, 4, 5, 6, 7, 8]
[2, 3, 4, 5, 6, 7, 8]
[4, 5, 6, 7, 8]

然后,考虑您的最终拼接并添加发生在循环外部的:

[6, 7, 8]

由于您的循环递增 size,一旦它收集了正好 size.

的所有子数组,它将退出

相反,我建议继续操作直到您的输入为空:

function chunkArrayInGroups(arr, size) {
  var array = [];
  while(arr.length > 0){
    var spliceArr = arr.splice(0,size);
    array.push(spliceArr);
  }
  return array;
}

这里的问题是您在整个迭代过程中减少了数组长度。 IE。你的数组在每次迭代中变得更小,而你的 x 不断增加。这意味着在您的最后一次迭代之前,您的 x 将为 6 并且数组长度将为 3,因此 x < arr.length 计算为 false 并且您的最后一次迭代不会发生。我能想到的最简单的解决方案是将原始数组长度存储到我命名为 stop 的变量中,并删除循环外不必要的最终数组推送。

function chunkArrayInGroups(arr, size) {
  var array = [];
  var stop = arr.length;
  for (var x = 0; x < stop; x+=size){
    var spliceArr = arr.splice(0,size);
    array.push(spliceArr);
  }
  return array;
}

console.log(chunkArrayInGroups([1,2,3,4,5,6,7], 2))

您将希望逐步使用大小来节省数组的循环次数。我们还保存了长度,这样就不会每次都获取它,因为它可以节省操作。您还会注意到我没有使用 var,因为您不应该使用它。请对普通变量使用 let,对您不打算重新分配的变量使用 const

function chunkArrayInGroups(arr, size) {
  let array = [];
  let arrayLength = arr.length;
  for (let i = 0; i < arrayLength; i+=size) {
    array.push(arr.slice(i, i+size));
  }
  return array
}

console.log(chunkArrayInGroups(["a", "b", "c", "d"], 2), [["a", "b"], ["c", "d"]])
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5], 3), [[0, 1, 2], [3, 4, 5]])
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 4), [[0, 1, 2, 3], [4, 5, 6, 7], [8]])
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2), [[0, 1], [2, 3], [4, 5], [6, 7], [8]])

splice 方法在每次迭代时更改数组的长度。这就是为什么您的循环在您预期之前退出的原因。你可以阅读更多关于 splice here.

splice 不同,slice 不会从数组中删除项目,这就是 lealceldeiro 答案会按预期工作的原因。

Kevin Bruccoleri 的回答看起来更清晰、更简短,但如果您有一个应用程序,您将数组存储到一个变量中,然后将其传递给函数,则该变量在函数执行后将为空,这可能会导致到您的应用程序中的错误。这就是数组基本上是对象的原因,但那是 javascript.

的科幻小说

function chunkArrayInGroups(arr, size) {
  var array = [];
  while (arr.length) {
    array.push(arr.splice(0, size))
  }
  return array
}

var nums = [0, 1, 2, 3, 4, 5, 6, 7, 8]
console.log('now it full', nums);
console.log(chunkArrayInGroups(nums, 2));
console.log('now it empty', nums);

使用slice复制原数组二 map()splice() 从 n 个索引

插入数组
const frankenSplice = (arr1, arr2, n) => {
    let arr = arr2.slice();

    arr1.map(e => {
        arr.splice(n, 0, e);
        n++;
    })

    return arr;
}