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