Javascript Для незавершенного цикла с массивом

Я пытаюсь построить цикл с массивом из 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');
}

изменение массива в цикле, пока он зациклен, никогда не является хорошей идеей

baao 14.06.2018 22:03

Почему бы и нет, если теоретически я контролирую это? В любом случае, я просто хочу понять, почему цикл останавливается на десятой позиции только тогда, когда в массиве 11 или 12 позиций?

Thiago Machado 14.06.2018 22:04

Поскольку вы изменяете массив внутри цикла

baao 14.06.2018 22:10
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
48
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это потому, что вы изменяете исходный массив во время итерации:

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 позиций за одну итерацию).


One way to have a code which performs that mentioned logic and leaves the array clear afterwards would be this.

Создайте функцию, которая выполняет следующие действия:

  • взять массив и размер группы
  • создать копию этого массива
  • получить нужное количество итераций
  • выполняй свою логику
  • return (пустой массив) и переназначить старый массив

Чтобы получить правильное количество итераций, разделите длину массива на размер группы и округлите его в большую сторону.

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.

Thiago Machado 14.06.2018 22:23

@ThiagoMachado Да, изменение этого цикла на while(x.length > 0) действительно сработает в этом случае, но это определенно неправильный путь. Чего именно пытаетесь добиться? (Я уверен, что есть лучшее решение)

Matus Dubrava 14.06.2018 22:30

Я хочу запустить весь массив, как я написал в сообщении, и убедиться, что массив будет очищен в конце.

Thiago Machado 14.06.2018 22:36

Спасибо! Это многое мне прояснило.

Thiago Machado 15.06.2018 19:43

Другие вопросы по теме