Я хочу иметь цикл foreach, в котором начальный массив изменяется внутри цикла.
например.
$array = array('red', 'blue'); foreach($array as $key => $value) { $array[] = 'white'; echo $value . '<br />'; }
в этом цикле цикл будет печатать красным и синим, хотя я добавляю еще один элемент внутри цикла.
есть ли способ изменить начальный массив внутри цикла, чтобы были добавлены новые элементы, и foreach будет использовать новый массив независимо от того, что изменилось?
Мне нужна такая логика для конкретной задачи:
У меня будет оператор if, который ищет ссылку. если эта ссылка существует, она добавляется в массив. контент ссылки будет извлечен для проверки, если он содержит другую ссылку. если это так, эта ссылка будет добавлена, и контент будет извлечен, так далее. Когда связь не будет найдена, цикл foreach выйдет
Я не думаю, что это возможно с циклом foreach
, по крайней мере так, как вы его написали: похоже, это не так, как работает foreach
; цитируя страницу руководства foreach
:
Примечание. Если массив не указан, foreach работает с копией указанного массива, а не с самим массивом.
Изменить: немного подумав об этой заметке, это действительно возможно, и вот решение:
В примечании говорится: « Если массив не указан »; что означает, что эта часть кода должна работать:
$i = 0; $array = array('red', 'blue'); foreach($array as $key => & $value) { $array[] = 'white'; echo $value . '<br />'; if ($i++ >= 5) { break; // security measure to ensure non-endless loop } }
Обратите внимание на значение &
before $value
.
И на самом деле он отображает:
red blue white white white white
Это означает добавление того, что &
на самом деле является решением, которое вы искали, для изменения массива изнутри цикла foreach
😉
Edit: и вот решение, которое я предложил, прежде чем думать об этом примечании:
Вы можете сделать это, используя цикл while, делая немного больше работы «вручную»; например :
$i = 0; $array = array('red', 'blue'); $value = reset($array); while ($value) { $array[] = 'white'; echo $value . '<br />'; if ($i++ >= 5) { break; // security measure to ensure non-endless loop } $value = next($array); }
Вы получите этот результат:
red blue white white white white
Вам нужно переместить назначение внутри цикла for и проверить длину массива на каждой итерации.
$array = array('red', 'blue'); for($i = 0; $i < count($array); $i++) { $value = $array[$i]; array_push($array, 'white'); echo $value . '<br />'; }
Будьте осторожны, это вызовет бесконечный цикл (белый будет добавлен в конец массива в каждом цикле).
Может быть, вы должны использовать другой способ, например:
$ar = array('blue', 'red'); while ($a = array_pop($ar) { array_push($ar, 'white'); }
Или что-то вроде этого …
Вы можете получить доступ к массиву с помощью ключа $
$array = array('red', 'blue'); foreach($array as $key => $value) { $array[$key] = 'white'; }
Чтобы иметь возможность напрямую изменять элементы массива в цикле, перед
$value
нужно указать&
. В этом случае значение будет присвоено по ссылке . [источник]
Все, что вам нужно сделать, чтобы ваш старый код был
предшествует
$value
&
вот так
$array = array('red', 'blue'); foreach($array as $key => &$value) {// <-- here $array[] = 'white'; echo $value . '<br />'; }
Контур while будет лучшим решением.
while (list ($key, $value) = each ($array) ) { $array[] = 'white'; echo $value . '<br />'; }
Если вам не нужна переменная $ key, как показывает ваш пример, вместо этого используйте $value = array_pop($array)
если бы list ($key, $value) = each ($array)
был бы менее дорогостоящим вариантом. см. @ enrico-carlesso's Answer Here
Поскольку ваш массив является секвенциальным (числовым, индексированным) и не ассоциативным, вы можете вместо этого использовать цикл for
.
for ($key = 0; $key < count($array); ++$key) { $value = $array[$i]; $array[] = 'white'; echo $value . '<br />'; }
Как примечание.
Я не понимаю, почему его &$value
и not &array
.
&$value
предложит вам изменить только текущий элемент внутри цикла. &array
предложит вам изменить все элементы массива в цикле, включая добавление / удаление элемента.