Я пытаюсь построить цикл с массивом из 12 позиций, обернуть 5 элементов и вставить другой код после этого интервала, но по какой-то причине цикл увеличивается только до 10. Почему цикл останавливается на десятой позиции только тогда, когда в массиве 11 или 12 позиций? Кто-нибудь может объяснить мне причину этого?
let x = [0,1,2,3,4,5,6,7,8,9,10,11];
x.map(_=> {
console.info("<div>");
x.splice(0,5).map((y,k)=>
console.info('item: ' + y)
)
console.info("</div>");
console.info('interval of 5 text');
});
x = [0,1,2,3,4,5,6,7,8,9,10,11];
for(i=0; i < x.length; i++){
let x2 = x.splice(0,5);
console.info("<div>");
for(j=0; j < x2.length; j++){
console.info('item: ' + x2[j]);
}
console.info("</div>");
console.info('interval of 5');
}
Почему бы и нет, если теоретически я контролирую это? В любом случае, я просто хочу понять, почему цикл останавливается на десятой позиции только тогда, когда в массиве 11 или 12 позиций?
Поскольку вы изменяете массив внутри цикла



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это потому, что вы изменяете исходный массив во время итерации:
let x2 = x.splice(0,5); // should be avoided.
С каждым изменением длина вашего массива также уменьшается.
Используйте Array.slice (...) вместо Array.splice (...)
let x = [0,1,2,3,4,5,6,7,8,9,10,11]
After a = **x.splice(0,5)** =>
x => [5,6,7,8,9,10,11]
a => [0,1,2,3,4]
After a = **x.slice(0,5)** =>
x => [0,1,2,3,4,5,6,7,8,9,10,11]
a => [0,1,2,3,4]
Поскольку вы используете условие (... i <x.length ...), после двух операций сращивание вы достигнете конца массива. (с петлей вы получите тот же случай)
Чтобы ответить на ваш вопрос, почему.
Позвольте мне немного прояснить этот цикл и просто оставить метод splice (поскольку он мутирует ваш массив) и записывать длину массива x в консоль на каждой итерации.
x = [0,1,2,3,4,5,6,7,8,9,10,11];
for(var i=0; i < x.length; i++){
let x2 = x.splice(0,5);
console.info(x.length);
}И посмотрим, что получится.
loop execution:
------------------------------
i | x.length | i < x.length
------------------------------
0 | 12 | true
1 | 7 | true
2 | 2 | false
вот почему ваш цикл заканчивается после второй итерации (которая является 10-й позицией, поскольку вы обрабатываете 5 позиций за одну итерацию).
Создайте функцию, которая выполняет следующие действия:
Чтобы получить правильное количество итераций, разделите длину массива на размер группы и округлите его в большую сторону.
let x = [0,1,2,3,4,5,6,7,8,9,10,11];
function customArrayLoop(arr, toTake) {
const arrCopy = [...arr];
const loopMax = Math.ceil(x.length / toTake);
for (let i = 0; i < loopMax; i++) {
let x2 = arrCopy.splice(0,5);
console.info("<div>");
for(let j=0; j < x2.length; j++){
console.info('item: ' + x2[j]);
}
console.info("</div>");
console.info('interval of 5');
}
return arrCopy;
}
x = customArrayLoop(x, 5);
console.info(x);Хотя это все еще не лучшее, что вы можете получить (поскольку вы хотите сохранить эту внутреннюю логику цикла), это гораздо более безопасное решение.
Спасибо! Я, вероятно, буду использовать while (x.length) вместо or map.
@ThiagoMachado Да, изменение этого цикла на while(x.length > 0) действительно сработает в этом случае, но это определенно неправильный путь. Чего именно пытаетесь добиться? (Я уверен, что есть лучшее решение)
Я хочу запустить весь массив, как я написал в сообщении, и убедиться, что массив будет очищен в конце.
Спасибо! Это многое мне прояснило.
изменение массива в цикле, пока он зациклен, никогда не является хорошей идеей