2010-02-27 104 views
26

tôi muốn có vòng lặp foreach nơi mảng ban đầu được thay đổi bên trong vòng lặp.thay đổi mảng ban đầu bên trong vòng lặp foreach?

ví dụ:

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

trong vòng lặp này vòng lặp sẽ in ra màu đỏ và xanh mặc dù tôi thêm phần tử khác trong vòng lặp.

có cách nào thay đổi mảng ban đầu bên trong vòng lặp để các phần tử mới sẽ được thêm vào và foreach sẽ sử dụng mảng mới bất kỳ thay đổi nào không?

tôi cần loại logic cho một nhiệm vụ cụ thể:

tôi sẽ có một câu lệnh if mà tìm kiếm một liên kết. nếu liên kết đó tồn tại, nó sẽ được thêm vào mảng. nội dung liên kết sẽ được tìm nạp để được kiểm tra nếu nó chứa một liên kết khác. nếu vậy, liên kết này được thêm vào và nội dung sẽ được tìm nạp, v.v .. khi không có liên kết nào được tạo thêm, vòng lặp foreach sẽ thoát ra

+1

Bạn có nhận ra rằng không có bất kỳ gián đoạn nào, ý tưởng của bạn sẽ chạy vào vòng lặp vô hạn? –

+0

đọc câu hỏi mới của tôi. – ajsie

Trả lời

43

Tôi không nghĩ rằng đây là có thể với một vòng lặp foreach, ít nhất là theo cách bạn đã viết nó: dường như không chỉ là cách làm việc của foreach; trích dẫn the manual page of foreach:

Lưu ý: Trừ khi mảng được tham chiếu, foreach hoạt động trên một bản sao của mảng được chỉ định và không phải là mảng chính nó.


Chỉnh sửa: sau khi suy nghĩ một chút về lưu ý rằng, nó thực sự có thể, và đây là giải pháp:

Những lưu ý nói "Trừ khi mảng được tham chiếu"; có nghĩa là phần mã này nên làm việc:

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

Lưu ý & trước $value.

Và nó thực sự hiển thị:

red 
blue 
white 
white 
white 
white 

Có nghĩa là thêm rằng & thực sự là giải pháp bạn đang tìm kiếm, để sửa đổi các mảng từ bên trong vòng lặp foreach ;-)


Chỉnh sửa: và đây là giải pháp tôi đã đề xuất trước khi nghĩ về ghi chú đó:

Bạn có thể làm điều đó bằng cách sử dụng vòng lặp while, thực hiện công việc nhiều hơn một chút "bằng tay"; ví dụ:

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

sẽ giúp bạn có được kết quả này:

red 
blue 
white 
white 
white 
white 
+0

hmm tại sao 4 màu trắng? Tôi chỉ muốn giá trị gia tăng được lặp lại một lần – ajsie

+1

Trong ví dụ tôi đã đăng, bạn nhận được 4 'trắng' vì bộ đếm bảo mật mà tôi đã sử dụng để ngăn chặn vòng lặp vô tận:' ngắt' sẽ buộc vòng lặp kết thúc sau 6 lần lặp * (Mã bạn cung cấp trong câu hỏi của bạn đã gây ra một vòng lặp vô tận và tôi không muốn điều đó trong các ví dụ của mình) * ;;; trong ứng dụng của bạn, tùy thuộc vào bạn để tìm một giải pháp phù hợp với nhu cầu của bạn để tránh lặp đi lặp lại :-) * (đánh giá từ câu hỏi của bạn, bạn có; ngay cả khi bạn không bao gồm nó như là một phần của câu hỏi của bạn) * –

+0

don 't thực sự hiểu tại sao giá trị $ được tham chiếu và không phải mảng $ ... nhưng nó tốt nếu nó hoạt động ... bạn đã kiểm tra mã này chưa? Chúc mừng. – DCC

7

Những gì bạn cần làm là chuyển bài tập bên trong vòng lặp for và kiểm tra độ dài của mảng mỗi lần lặp.

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

Hãy cẩn thận, điều này sẽ gây ra một vòng lặp vô hạn (màu trắng sẽ được thêm vào cuối của mảng ở mỗi vòng lặp).

+1

Trong khi câu trả lời trước đó đã được chấp nhận, điều này thực sự làm việc tốt hơn nhiều cho tôi để hoàn thành mục tiêu ảnh hưởng đến một mảng từ bên trong một vòng lặp. Sử dụng câu trả lời ở trên (câu trả lời đúng) giữ lại đặt lại con trỏ trong mảng gây ra tất cả các loại vấn đề. Sử dụng cái này. Đối với nhà văn, cảm ơn, và xin vui lòng không phải là mảng $ [$ i] bị coi nhẹ trong câu trả lời của bạn. – Dormouse

4

Có lẽ bạn nên sử dụng một số cách khác, như:

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

Hoặc một cái gì đó như thế này ...

+0

làm cách nào để đảm bảo rằng màu trắng chỉ được thêm và in ra một lần? gây ra mã của bạn cho một vòng lặp vô hạn – ajsie

+0

Tôi không. Như được chỉ ra là bình luận cho câu hỏi, là lập trình viên viết mã thông minh ... Rõ ràng là được viết bởi tôi nó sẽ chạy mãi mãi, nó chỉ là một ví dụ. –

+0

@noname bạn có thể sử dụng nếu .. else ... trước một array_push, và in_array để kiểm tra xem nó đã có trên một mảng trùng lặp mà chỉ giữ "ghi" :) – DCC

1

Bạn có thể truy cập vào mảng bằng cách sử dụng thứ tự $ key

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

bạn không hiểu câu hỏi, đây không phải là câu trả lời –

1

Trong để có thể trực tiếp sửa đổi phần tử mảng trong vòng lặp trước $value với &. Trong trường hợp đó, giá trị sẽ được chỉ định bởi reference. [source]

Tất cả bạn phải làm gì để mã cũ của bạn là

trước $value với &

như vậy

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

Một vòng lặp while sẽ là một giải pháp tốt hơn .

while (list ($key, $value) = each ($array)) { 
    $array[] = 'white'; 
    echo $value . '<br />'; 
} 

Nếu bạn không cần phải biến $ key, như ví dụ của bạn gợi ý sau đó sử dụng $value = array_pop($array) thay vì nếu list ($key, $value) = each ($array) sẽ là một lựa chọn ít tốn kém. xem @enrico-carlesso's Trả lời Here

Vì mảng của bạn là dãy số (số, được lập chỉ mục) và không liên kết nên bạn có thể sử dụng vòng lặp for thay thế.

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

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

Lưu ý phụ.

Tôi không hiểu lý do tại sao &$value và không &array.

&$value sẽ đề xuất bạn chỉ có thể sửa đổi phần tử hiện tại trong vòng lặp. &array sẽ đề xuất bạn có thể sửa đổi tất cả các phần tử mảng trong vòng lặp, bao gồm thêm/xóa phần tử.

Các vấn đề liên quan