Сценарии базового алгоритма, вырезая массив с помощью функции сплайсинга в 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]].

Я знаю, что это не сложный вопрос, и есть много способов лучше подойти к нему, но могу ли я узнать, какова логическая ошибка в этом коде? Большое спасибо!

5 ответов

Решение

Это может помочь добавить 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;
}

Вместо splice использование slice, Это также гарантирует, что исходный массив не был изменен.

Вот так (работает демо):

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]]

Вы захотите пошагово использовать размер, чтобы сэкономить на количестве циклов в массиве. Мы также сохраняем длину, чтобы она не извлекалась каждый раз, когда сохраняются операции. Также вы заметите, что я не использую 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]])

Проблема в том, что вы сокращаете длину массива на протяжении всей итерации. Т.е. ваш массив уменьшается с каждой итерацией, а ваш 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))

splice Метод меняет длину массива на каждой итерации. Вот почему ваш цикл выходит раньше, чем вы ожидаете. Вы можете прочитать больше о сплайсинге здесь.

В отличие от splice, slice не удалит элементы из массива, поэтому ответ lealceldeiro будет работать так, как ожидается.

Ответ Кевина Бруколери выглядит чище и короче, но если у вас есть приложение, в котором вы храните массив в переменной, а затем передаете его функции, эта переменная будет пустой после выполнения функции, что может привести к ошибкам в вашем приложении., Вот почему массивы в основном объектные, но это научная фантастика 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;
}
Другие вопросы по тегам