Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Запутался в цикле в трех соснах


Автор: motorway 15.9.2011, 15:18
Что-то запутался вроде бы в простой вещи - добавление элементов в массив в процессе for each.
В общем, мне нужно сделать вот что. Есть код, который выполняется для элементов массива. Но при некоторых условиях нужно, чтобы в массив добавились еще элементы, и для них выполнился тот же код с начала цикла.
Но сегодня ночью сидел, и что-то мне там не понравилось - при добавлении элемента в конец код продолжал исполняться сразу для нового элемента.
А сейчас вот такой код пробую:
Код

$ar=array(11);
foreach ($ar as $a)
{
echo $a."<BR>";
echo var_dump($ar); echo "<BR>";
$ar[]=22;
echo var_dump($ar); echo "<BR>";
echo $a."<BR>";
};

То есть, получается, я добавил в массив число 22, видно, что он добавился, но код для него не выполнился, так как 22 не вывело, а только 2 раза 11.
По идее, я бы ожидал, что такой код два раза должен вывести 11 и два раза 22. Но сначала у меня было, что он выводил 11, а потом сразу 22, а здесь наоборот - только 11, а до 22 он даже не доходит.
В чем тут дело?
(ну и собственно, он должен на каждой итерации добавлять в конец число, раз стоит [])

Автор: solenko 15.9.2011, 15:30
Думаю, дело в том, что foreach делает копию массива и проходит по нему во избежание вечного цикла (как было-бы в случае с вашим кодом)

Автор: motorway 15.9.2011, 15:35
Ну а если мне как раз нужно продолжать добавлять в массив элементы - конец будет при наступлении некоторого условия? Не писать же еще один код для добавляемых элементов - нужно, чтобы тело цикла выполнялось для новых элементов так же

Добавлено через 52 секунды
К тому же, вечные циклы вполне работают в других случаях (for и т.п.) Особых запретов на них нет... smile

Автор: motorway 15.9.2011, 16:35
Ну так всё-таки есть способ добавить в цикле в конец массива элемент, чтобы по нему тоже прошёлся цикл?

Автор: newbee 15.9.2011, 16:44
motorway, почитай наконец документацию на foreach. Используй for.

Автор: motorway 15.9.2011, 16:54
Да я почитал только что, только странно это - они обычно были взаимозаменяемы.

Автор: motorway 15.9.2011, 17:15
Тогда возьмем такой код:
Код

$ar=array(11);
for ($i=0; $i<count($ar); $i++)
{
echo $ar[$i].'<BR>';

$ar[]="22";
echo $i;
$c++;
if ($c==20) break;

};

В начале цикла count($ar)=1, поэтому цикл должен остановиться после первой итерации.
Однако неведомым образом после добавления элемента он продолжается, т.е. условие как бы пересчитывается, хотя первое вычисление дало жестко 1, и нет оснований пересчитывать его снова.
И только установка брейка избавляет от бесконечности цикла.

Автор: newbee 15.9.2011, 17:21
Цитата(motorway @  15.9.2011,  18:15 Найти цитируемый пост)
В начале цикла count($ar)=1, поэтому цикл должен остановиться после первой итерации.
Однако неведомым образом после добавления элемента он продолжается, т.е. условие как бы пересчитывается, хотя первое вычисление дало жестко 1, и нет оснований пересчитывать его снова.
По твоей логике, код
Код

(for i=0;i<10;i++){}
должен выполняться бесконечно, ведь i<10 однажды уже было вычислено и нет оснований его пересчитывать?smile

Наверное тебе стоить более внятно рассказать, что ты пытаешься сделать, потому что поведение foreach тебя не устраивает, портивоположное поведение for - тоже. Я тебя не понимать.

Автор: motorway 15.9.2011, 17:27
Видимо, переутомление дает о себе знать, ну и некоторые вопросы имеют свои особенности. Например, почему в PHP for each не позволил добавлять в конец элементы, а в for можно.
У меня есть массив урлов, я выполняю запросы к ним - и если на странице нет нужного результата, то добавляю в массив еще урл и т.д.
Нужно, что для каждого добавленного урла выполнялся один и тот же код.
Насчет i<count($ar) понял, в чем тут дело. smile
Я переделал на for, второе условие вообще убрал, добавил в сам код условие на break. Вроде бы уже начинает получаться то, что нужно.

Автор: Photon 21.9.2011, 20:15
А не проще через while цикл организовать? Вот примерно как-то так..
Код

$ar = array(1);
$i = 0;
while(isset($ar[$i])) {
   echo $ar[$i];
   $ar[] = $i + 2;
   if ($i == 5) {
       break;
   }
   $i++;
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)