2010-02-27 17 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會建議您可以修改循環中的所有數組元素,包括添加/刪除元素。