Изменить начальный массив внутри цикла foreach?
Я хочу иметь цикл foreach, в котором начальный массив изменяется внутри цикла.
например.
$array = array('red', 'blue');
foreach($array as $key => $value) {
$array[] = 'white';
echo $value . '<br />';
}
в этом цикле цикл будет печатать красным и синим, хотя я добавляю еще один элемент внутри цикла.
Есть ли способ изменить начальный массив внутри цикла, чтобы новые элементы были добавлены, и foreach будет использовать новый массив, который изменился?
Мне нужна такая логика для конкретной задачи:
У меня будет оператор if, который ищет ссылку. если эта ссылка существует, она добавляется в массив. контент ссылки будет извлечен для проверки, если он содержит другую ссылку. если это так, эта ссылка добавляется, и контент будет извлечен, так далее. Когда связь не будет создана, цикл foreach выйдет из
Ответы
Ответ 1
Я не думаю, что это возможно с циклом 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
}
}
Обратите внимание на &
до $value
.
И на самом деле он отображает:
red
blue
white
white
white
white
Что означает добавление, что &
на самом деле является решением, которое вы искали, для изменения массива из цикла foreach
; -)
Изменить: и вот решение, которое я предложил, прежде чем думать об этом примечании:
Вы можете сделать это, используя цикл 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
Ответ 2
Что вам нужно сделать, это переместить назначение внутри цикла for и проверить длину массива на каждой итерации.
$array = array('red', 'blue');
for($i = 0; $i < count($array); $i++)
{
$value = $array[$i];
array_push($array, 'white');
echo $value . '<br />';
}
Будьте осторожны, это вызовет бесконечный цикл (белый будет добавлен в конец массива в каждом цикле).
Ответ 3
Может быть, вы должны использовать другой способ, например:
$ar = array('blue', 'red');
while ($a = array_pop($ar) {
array_push($ar, 'white');
}
Или что-то вроде этого...
Ответ 4
Вы можете получить доступ к массиву с помощью $key
$array = array('red', 'blue');
foreach($array as $key => $value) {
$array[$key] = 'white';
}
Ответ 5
Чтобы иметь возможность напрямую изменять элементы массива в цикле перед $value
с &
. В этом случае значение будет присвоено reference. [источник]
Все, что вам нужно сделать для вашего старого кода, это
предшествует $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 Отвечать здесь
Поскольку ваш массив является секвенциальным (числовым, индексированным) и не ассоциативным, вместо этого вы можете использовать цикл for
.
for ($key = 0; $key < count($array); ++$key) {
$value = $array[$i];
$array[] = 'white';
echo $value . '<br />';
}
Как примечание.
Я не понимаю, почему его &$value
, а не &array
.
&$value
предложит вам изменить только текущий элемент в цикле.
&array
предложит вам изменить все элементы массива в цикле, включая добавление/удаление элемента.