2010-02-27 52 views
26

我想有一个foreach循环,其中初始数组在循环内更改。更改foreach循环内的初始数组?

例如。

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

在这个循环中,循环会打印出红色和蓝色,尽管我在循环中添加了另一个元素。

是否有任何方法来改变循环内的初始数组,所以新的元素将被添加,并且foreach将使用新的数组,无论发生了什么变化?

我需要这种逻辑的特定任务:

我将有一个声明,如果搜索的链接。如果该链接存在,则将其添加到数组中。如果链接内容包含其他链接,链接内容将被提取以进行检查。如果是的话,这个链接被添加,并且内容将被提取,等等等等。当没有进一步建立链接时,foreach循环将退出

+1

你知道没有任何突破,你的想法会陷入无限循环吗? – 2010-02-27 16:45:25

+0

阅读我的新问题。 – ajsie 2010-02-27 16:48:49

回答

43

我不认为这是可能的一个foreach循环,至少你的方式写道:似乎只是foreach工作的方式;引用the manual page of foreach

注:除非数组是被引用,foreach指定数组的一个副本 ,而不是 阵列本身进行操作。


编辑:思考一些有关这个音符后,它实际上是可能的,而且这里的解决方案:

票据上写着:“除非数组是被引用”;这意味着这个代码部分应该工作:在&之前$value

$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 
    } 
} 

注。

,它实际上显示:

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 
+0

嗯为什么4白?我只希望增加的值被迭代一次 – ajsie 2010-02-27 17:00:22

+1

在我发布的例子中,由于我用来防止无限循环的安全计数器,所以得到4'white':'break'将强制循环在6次迭代后结束* (你在你的问题中提供的代码导致了无限循环,我不想在我的例子中)* ;;;在你的应用程序中,你可以找到一个适合你避免无限循环的解决方案:-) *(从你的问题来看,你有;即使你没有把它作为你问题的一部分)* – 2010-02-27 17:07:02

+0

don '真的不明白为什么要引用$ value而不是$ array ...但是如果它能够正常工作,那么这很好...你测试了这个代码吗?干杯。 – DCC 2010-02-27 17:22:28

7

你需要做的是在for循环中移动赋值并在每次迭代中检查数组的长度。

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

要小心,这将导致无限循环(白色将被添加到每个循环数组的末尾)。

+1

虽然之前的答案已被接受,但实际上,这对我来说能够更好地实现从循环内影响数组的目标。使用上述答案(“正确的”)会不断重置数组中的指针,导致各种问题。使用这个。对作者来说,谢谢,并且请不要$ array [$ i]在你的回答中被错误地引用。 – Dormouse 2012-11-21 18:28:13

4

也许你应该使用一些其他的方式,如:

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

或者这样的事情...

+0

你如何确保只有白色被添加和打印一次?导致你的代码给出了无限循环 – ajsie 2010-02-27 17:00:59

+0

我没有。正如对这个问题的评论所指出的那样,是由程序员来编写聪明的代码......很明显,就像我写的那样,它会永远运行,这只是一个例子。 – 2010-02-27 17:08:50

+0

@noname你可以使用if .. else ... array_push之前,并in_array检查它是否已经在一个重复的数组,只是保持“记录”:) – DCC 2010-02-27 17:16:33

1

您可以通过使用$键

$array = array('red', 'blue'); 
foreach($array as $key => $value) { 
    $array[$key] = 'white'; 
} 
+0

你不明白这个问题,这不是一个答案 – 2014-12-08 11:25:09

1

为了访问阵列能够直接修改环 之前的阵列元素在$value之前&。在这种情况下,该值将由 reference分配。 [source]

所有你必须做你的旧代码是

上一页$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 />'; 
} 

如果您不需要$关键变量,如你的例子说明,然后使用$value = array_pop($array),而是如果list ($key, $value) = each ($array)将是一个更便宜的选择。请参阅@enrico-carlesso's答案Here

由于您的数组是相加(数字,索引)而不是关联的,因此您可以使用for循环代替。

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

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

作为一个侧面说明。

我不明白为什么它的&$value而不是&array

&$value建议您只能修改循环中的当前元素。 &array会建议您可以修改循环中的所有数组元素,包括添加/删除元素。