изменить начальный массив внутри цикла foreach?

php

19146 просмотра

5 ответа

31191 Репутация автора

я хочу иметь цикл foreach, где исходный массив изменяется внутри цикла.

например.

$array = array('red', 'blue');
foreach($array as $key => $value) {
    $array[] = 'white';
    echo $value . '<br />';
}

в этом цикле цикл напечатает красный и синий, хотя я добавляю еще один элемент внутри цикла.

Есть ли способ изменить начальный массив внутри цикла, чтобы новые элементы были добавлены и foreach будет использовать новый массив независимо от того, что изменилось?

мне нужна такая логика для конкретной задачи:

у меня будет заявление if, которое ищет ссылку. если эта ссылка существует, она добавляется в массив. содержание ссылки будет выбрано для проверки, если оно содержит другую ссылку. если это так, эта ссылка добавляется, и содержимое будет извлечено, и так далее ... когда ссылка не будет найдена, цикл foreach завершится

Автор: ajsie Источник Размещён: 27.02.2010 04:38

Ответы (5)


8 плюса

6480 Репутация автора

Вам нужно переместить присваивание внутри цикла for и проверять длину массива каждую итерацию.

$array = array('red', 'blue');
for($i = 0; $i < count($array); $i++)
{
   $value = $array[$i];
   array_push($array, 'white');
   echo $value . '<br />';
}

Будьте осторожны, это вызовет бесконечный цикл (белый будет добавляться в конец массива в каждом цикле).

Автор: MrValdez Размещён: 27.02.2010 04:45

4 плюса

5357 Репутация автора

Может быть, вы должны использовать другой способ, например:

$ar = array('blue', 'red');
while ($a = array_pop($ar) {
     array_push($ar, 'white');
}

Или как то так ...

Автор: Enrico Carlesso Размещён: 27.02.2010 04:46

45 плюса

351350 Репутация автора

Решение

Я не думаю, что это возможно с 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
Автор: Pascal MARTIN Размещён: 27.02.2010 04:47

1 плюс

35 Репутация автора

Вы можете получить доступ к массиву, используя ключ $

$array = array('red', 'blue');
foreach($array as $key => $value) {
    $array[$key] = 'white';
}
Автор: freelivenet Размещён: 20.09.2013 10:36

1 плюс

2273 Репутация автора

Для того , чтобы иметь возможность непосредственно изменять элементы массива в пределах предшествуют контур $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)нее вариант if, который будет менее дорогим. см @ Энрико-Carlesso в ответ здесь

Поскольку ваш массив является последовательным (числовым, индексированным) и не ассоциативным, вы можете forвместо этого использовать цикл.

for ($key = 0; $key < count($array); ++$key) {
    $value = $array[$i];

    $array[] = 'white';
    echo $value . '<br />';
}

Как примечание стороны.

Я не понимаю, почему это так &$valueи нет &array.

&$valueПредполагается, что вы можете изменить только текущий элемент в цикле. &arrayПредполагается, что вы можете изменить все элементы массива в цикле, включая добавление / удаление элемента.

Автор: TarranJones Размещён: 11.03.2016 09:37
Вопросы из категории :
32x32