Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Pętla foreach zagnieżdżona w for - problem z indeksami
Forum PHP.pl > Forum > PHP
jurcio6
Witam.

Mam pewien problem z indeksami. Kod:

  1. //$answers to dwuwymiarowa tablica rekordów pobranych z bazy - załóżmy, że tych rekordów ma tam 3
  2. for($i=0; $i<3; $i++)
  3. {
  4. //jakiś kod do wykonania
  5. $j = 1;
  6. foreach($answers as $row)
  7. {
  8. //jakiś kod do wykonania - $row coś tam - wiadomo, ale problem poniżej:
  9. echo $j.", ";
  10. $j++;
  11. }
  12. }


I teraz problem mam następujący: wynikiem takiej pętli jest: "1, 2, 3, 4, 5, 6, 7, 8, 9" - jakim cudem, skoro przy każdej iteracji pętli zewnętrznej for ustawiam licznik $j =1? Czy wynikiem nie powinno być "1, 2, 3, 1, 2, 3, 1, 2, 3"? Jak uzyskać taki efekt?

Proszę o pomoc! Z góry dzięki.
Piogola
Jesteś pewien, że masz 3 rekordy, a nie 9 ?
darko
Pętla foreach ma to do siebie, że iteruje po całej tablicy bez żadnych ograniczeń,natomiast Ty ustawiasz wartość zmiennej $j już poza nią. To co robi teraz ten kod, to trzykrotny foreach po całej tablicy. Jeśli chciałbyś wyciągnąć co trzeci rekord to należałoby zrobić małą modyfikację związaną z wykorzystaniem reszty z dzielenia (sprawdzasz czy modulo % 3 z $j == 0) i wszystko w jednym foreachu.
jurcio6
Pętla działa w porządku - tzn. zgodnie z moim zamierzeniem. Wykorzystuję ją przy ankietach i służy ona konkretnie do wypisania wszystkich odpowiedzi do danego pytania - po pytaniach iteruje for, po odpowiedziach foreach - tu wszystko z pewnością jest dobrze. Wyciąłem to po prostu z kontekstu i dlatego wygląda to tak, jakby iterowała 3 razy po tym samym - w rzeczywistości przy każdej iteracji zmienia się argument $answers.

Problem jest taki, że chciałem nazywać odpowiedzi dla każdego pytania 1, 2, 3, 4.. , a tutaj nie resetuje się ten index $j i mi to uniemożliwia. Konkretnie chodzi o atrybuty value dla inputów. Nie chcę korzystać z $row['question_id'], który jest wyciągany z bazy i po czasie może przyjmować dosyć wysokie wartości. Cały kod wygląda mniej więcej tak:
  1. echo "<table align=\"center\">";
  2. for($i=0; $i<$nq; $i++)
  3. {
  4. echo "\n<tr><td style=\"padding: 15px 0px 5px 0px;\"><b>Pytanie ";
  5. echo $i+1 .": <i>".$questions[$i]['question_text']."</i></b>";
  6. if($questions[$i]['multiple_choice']==1)
  7. echo " [wybór wielokrotny]";
  8. echo "</td></tr>\n<tr><td style=\"padding-left: 30px;\">";
  9. $j = 1;
  10. foreach($answers as $row)
  11. {
  12. if($questions[$i]['question_id'] == $row['question_id'])
  13. if($questions[$i]['multiple_choice']==1)
  14. echo "\n<label name=\"".$row['question_id']."\"><input type=\"checkbox\" name=\"question_".$i."[]\" value=\"".$j."\" />".$row['answer_text']."</label><br />";
  15. else
  16. echo "\n<label name=\"".$row['question_id']."\"><input type=\"radio\" name=\"question_".$i."\" value=\"".$j."\" />".$row['answer_text']."</label><br />";
  17. $j++;
  18. }
  19. echo "</td></tr>";
  20. }
  21. echo "\n</table>";

Wersja mocno robocza smile.gif

//edit: oczywiście chodzi o wartości value dla inputów, a nie o name.
darko
Dodaj dla porządku odpowiednie nawiasy klamrowe do instrukcji warunkowych if i sprawdź efekt.
jurcio6
Niestety nic się nie zmieniło. Poszczególne pola <input.. /> nadal przyjmują wartości value="" od 1 do 23 (tyle jest rekordów).

  1. echo "<table align=\"center\">";
  2. for($i=0; $i<$nq; $i++)
  3. {
  4. echo "\n<tr><td style=\"padding: 15px 0px 5px 0px;\"><b>Pytanie ";
  5. echo $i+1 .": <i>".$questions[$i]['question_text']."</i></b>";
  6. if($questions[$i]['multiple_choice']==1)
  7. {
  8. echo " [wybór wielokrotny]";
  9. }
  10. echo "</td></tr>\n<tr><td style=\"padding-left: 30px;\">";
  11. $j = 1;
  12. foreach($answers as $row)
  13. {
  14. if($questions[$i]['question_id'] == $row['question_id'])
  15. {
  16. if($questions[$i]['multiple_choice']==1)
  17. {
  18. echo "\n<label name=\"".$row['question_id']."\"><input type=\"checkbox\" name=\"question_".$i."[]\" value=\"".$j."\" />".$row['answer_text']."</label><br />";
  19. }
  20. else
  21. {
  22. echo "\n<label name=\"".$row['question_id']."\"><input type=\"radio\" name=\"question_".$i."\" value=\"".$j."\" />".$row['answer_text']."</label><br />";
  23. }
  24. }
  25. $j++;
  26. }
  27. echo "</td></tr>";
  28. }
  29. echo "\n</table>";


Efekt:
  1. <table align="center">
  2. <tr><td style="padding: 15px 0px 5px 0px;"><b>Pytanie 1: <i>Czy wolisz kolory jasne czy ciemne?</i></b></td></tr>
  3. <tr><td style="padding-left: 30px;">
  4. <label name="92"><input type="radio" name="question_0" value="1" />jasne</label><br />
  5. <label name="92"><input type="radio" name="question_0" value="2" />ciemne</label><br />
  6. <label name="92"><input type="radio" name="question_0" value="3" />jest mi to obojętne</label><br /></td></tr>
  7.  
  8. <tr><td style="padding: 15px 0px 5px 0px;"><b>Pytanie 2: <i>Czy wolisz odcienie stonowane czy jaskrawe?</i></b></td></tr>
  9. <tr><td style="padding-left: 30px;">
  10. <label name="93"><input type="radio" name="question_1" value="4" />jaskrawe</label><br />
  11. <label name="93"><input type="radio" name="question_1" value="5" />stonowane</label><br />
  12. <label name="93"><input type="radio" name="question_1" value="6" />jest mi to obojętne</label><br /></td></tr>
  13. <tr><td style="padding: 15px 0px 5px 0px;"><b>Pytanie 3: <i>Jakiego koloru koszulki lubisz nosić?</i></b> [wybór wielokrotny]</td></tr>
  14. <tr><td style="padding-left: 30px;">
  15. <label name="94"><input type="checkbox" name="question_2[]" value="7" />białe</label><br />
  16.  
  17. <label name="94"><input type="checkbox" name="question_2[]" value="8" />czarne</label><br />
  18. <label name="94"><input type="checkbox" name="question_2[]" value="9" />zielone</label><br />
  19. <label name="94"><input type="checkbox" name="question_2[]" value="10" />czerwone</label><br />
  20. <label name="94"><input type="checkbox" name="question_2[]" value="11" />żółte</label><br />
  21. <label name="94"><input type="checkbox" name="question_2[]" value="12" />niebieskie</label><br /></td></tr>
  22. <tr><td style="padding: 15px 0px 5px 0px;"><b>Pytanie 4: <i>Czy lubisz odcienie szarości?</i></b></td></tr>
  23. <tr><td style="padding-left: 30px;">
  24. <label name="95"><input type="radio" name="question_3" value="13" />tak</label><br />
  25. <label name="95"><input type="radio" name="question_3" value="14" />nie</label><br /></td></tr>
  26.  
  27. <tr><td style="padding: 15px 0px 5px 0px;"><b>Pytanie 5: <i>Jaki jest twój ulubiony kolor?</i></b></td></tr>
  28. <tr><td style="padding-left: 30px;">
  29. <label name="96"><input type="radio" name="question_4" value="15" />pomarańczowy</label><br />
  30. <label name="96"><input type="radio" name="question_4" value="16" />fioletowy</label><br />
  31. <label name="96"><input type="radio" name="question_4" value="17" />niebieski</label><br />
  32. <label name="96"><input type="radio" name="question_4" value="18" />żółty</label><br />
  33. <label name="96"><input type="radio" name="question_4" value="19" />zielony</label><br />
  34. <label name="96"><input type="radio" name="question_4" value="20" />czerwony</label><br />
  35. <label name="96"><input type="radio" name="question_4" value="21" />biały</label><br />
  36.  
  37. <label name="96"><input type="radio" name="question_4" value="22" />czarny</label><br />
  38. <label name="96"><input type="radio" name="question_4" value="23" />turkusowy</label><br /></td></tr>


Pożądany efekt:
  1. <table align="center">
  2. <tr><td style="padding: 15px 0px 5px 0px;"><b>Pytanie 1: <i>Czy wolisz kolory jasne czy ciemne?</i></b></td></tr>
  3. <tr><td style="padding-left: 30px;">
  4. <label name="92"><input type="radio" name="question_0" value="1" />jasne</label><br />
  5. <label name="92"><input type="radio" name="question_0" value="2" />ciemne</label><br />
  6. <label name="92"><input type="radio" name="question_0" value="3" />jest mi to obojętne</label><br /></td></tr>
  7.  
  8. <tr><td style="padding: 15px 0px 5px 0px;"><b>Pytanie 2: <i>Czy wolisz odcienie stonowane czy jaskrawe?</i></b></td></tr>
  9. <tr><td style="padding-left: 30px;">
  10. <label name="93"><input type="radio" name="question_1" value="1" />jaskrawe</label><br />
  11. <label name="93"><input type="radio" name="question_1" value="2" />stonowane</label><br />
  12. <label name="93"><input type="radio" name="question_1" value="3" />jest mi to obojętne</label><br /></td></tr>
  13. <tr><td style="padding: 15px 0px 5px 0px;"><b>Pytanie 3: <i>Jakiego koloru koszulki lubisz nosić?</i></b> [wybór wielokrotny]</td></tr>
  14. <tr><td style="padding-left: 30px;">
  15. <label name="94"><input type="checkbox" name="question_2[]" value="1" />białe</label><br />
  16. <label name="94"><input type="checkbox" name="question_2[]" value="1" />czarne</label><br />
  17. <label name="94"><input type="checkbox" name="question_2[]" value="1" />zielone</label><br />
  18. <label name="94"><input type="checkbox" name="question_2[]" value="1" />czerwone</label><br />
  19. <label name="94"><input type="checkbox" name="question_2[]" value="1" />żółte</label><br />
  20. <label name="94"><input type="checkbox" name="question_2[]" value="1" />niebieskie</label><br /></td></tr>
  21. <tr><td style="padding: 15px 0px 5px 0px;"><b>Pytanie 4: <i>Czy lubisz odcienie szarości?</i></b></td></tr>
  22. <tr><td style="padding-left: 30px;">
  23. <label name="95"><input type="radio" name="question_3" value="1" />tak</label><br />
  24. <label name="95"><input type="radio" name="question_3" value="2" />nie</label><br /></td></tr>
  25.  
  26. <tr><td style="padding: 15px 0px 5px 0px;"><b>Pytanie 5: <i>Jaki jest twój ulubiony kolor?</i></b></td></tr>
  27. <tr><td style="padding-left: 30px;">
  28. <label name="96"><input type="radio" name="question_4" value="1" />pomarańczowy</label><br />
  29. <label name="96"><input type="radio" name="question_4" value="2" />fioletowy</label><br />
  30. <label name="96"><input type="radio" name="question_4" value="3" />niebieski</label><br />
  31. <label name="96"><input type="radio" name="question_4" value="4" />żółty</label><br />
  32. <label name="96"><input type="radio" name="question_4" value="5" />zielony</label><br />
  33. <label name="96"><input type="radio" name="question_4" value="6" />czerwony</label><br />
  34. <label name="96"><input type="radio" name="question_4" value="7" />biały</label><br />
  35.  
  36. <label name="96"><input type="radio" name="question_4" value="1" />czarny</label><br />
  37. <label name="96"><input type="radio" name="question_4" value="2" />turkusowy</label><br /></td></tr>


//ignore na pola checkbox - je wiem jak obsłużyć smile.gif

Nadal nie udało mi się uporać z tym problemem - jakieś pomysły? ;/
vermis
Wykonałem ten twój kod i działa poprawnie. Jesteś pewien, że u ciebie wykonuje się dokładnie to co wkleiłeś?
jurcio6
Dla pewności wykonałem kod jeszcze raz i niestety jest to, co było, czyli value w inputach przyjmują wartości od 1 do 23, a nie tak, jak chcę. Naprawdę nie wiem czemu.

Pracuję na wamp server, PHP 5.3.0 - może przez średnio aktualną wersję? Choć szczerze mówiąc teraz nie jest najlepszy czas na zmiany oprogramowania - muszę szybko skończyć ten projekt.
TheTester
I ten pierwszy, najprostszy przykład też Ci nie działa? A mógłbyś dla tego uproszczonego przykładu zrobić print_r testowej tablicy jaką tam podajesz?
greycoffey
Btw. optymalizacja pierwszego przykładu:
  1. <?php
  2. // ...
  3. $j = 0; // zamiast $j=0
  4. foreach($answers as $row)
  5. {
  6. //jakiś kod do wykonania - $row coś tam - wiadomo, ale problem poniżej:
  7. echo ++$j.", "; //dodajemy preinkrementacje
  8. // usuawmy $j++;
  9. }
  10. ?>
donpablo
Cytat
teraz problem mam następujący: wynikiem takiej pętli jest: "1, 2, 3, 4, 5, 6, 7, 8, 9" - jakim cudem, skoro przy każdej iteracji pętli zewnętrznej for ustawiam licznik $j =1? Czy wynikiem nie powinno być "1, 2, 3, 1, 2, 3, 1, 2, 3"? Jak uzyskać taki efekt?


Jak się pisze bzdury to się ma problemy. Proponuje na poczatek zapoznać się z podstawami działania pętli. Poczatkowy fragment skryptu robi dokładnie to co powinien robić - bo tak napisałeś. To samo dotyczy tablic wielowymiarowych.
By uzyskac efekt 1,2,3 trzeba to napisać - chocby tak:
  1. foreach ($answers as $id => $row )
  2. {
  3. for($i=0, $j=1; $i<sizeof($row); $i++, $j++) //lub zamiast $i<sizeof($row) -> $i<3 o ile ilośc komórek równa jest 3
  4. {
  5. echo $j;
  6. }
  7. }

jurcio6
Siadłem ze świeżym umysłem i od razu znalazłem błąd - na który nikt w tym topicu nie wpadł...

Donpablo - być może wiesz dużo, ale nie wpadłeś na najprostsze rozwiązanie. Może i nie znam na tyle dobrze mechanizmów PHP, ale jeśli bym znał, to bym nie potrzebował pomocy na tym forum ani gdziekolwiek indziej. W każdym razie w tym wypadku nie tu leżał problem... pętle działały tak, jak było to przez mnie zamierzone - jedyną rzeczą, którą zrobiłem źle, to inkrementacja $j - powinna ona być tylko wtedy, gdy warunek jest spełniony (czyli gdy znajdę odpowiednie pole), a było zrobione tak, że wykonuje się zawsze (niezależnie od spełnienia warunku). Dodatkowo zmieniłem pętle for na foreach - dla własnej wygody. Dzięki wszystkim za chęci smile.gif

Rozwiązanie:
  1. foreach($questions as $q_row)
  2. {
  3. echo "\n<tr><td style=\"padding: 15px 0px 5px 0px;\"><b>Pytanie ";
  4. echo $i+1 .": <i>".$q_row['question_text']."</i></b>";
  5. if($q_row[$i]['multiple_choice']==1)
  6. {
  7. echo " [wybór wielokrotny]";
  8. }
  9. echo "</td></tr>\n<tr><td style=\"padding-left: 30px;\">";
  10. $j = 0;
  11. foreach($answers as $a_row)
  12. {
  13. if($q_row['question_id'] == $a_row['question_id'])
  14. {
  15. if($q_row['multiple_choice']==1)
  16. {
  17. ++$j; //PROBLEM ROZWIĄZANY
  18. echo "\n<label name=\"".$a_row['question_id']."\"><input type=\"checkbox\" name=\"question_".$i."[]\" value=\"".$j."\" />".$a_row['answer_text']."</label><br />";
  19. }
  20. else
  21. {
  22. ++$j; //PROBLEM ROZWIĄZANY
  23. echo "\n<label name=\"".$a_row['question_id']."\"><input type=\"radio\" name=\"question_".$i."\" value=\"".$j."\" />".$a_row['answer_text']."</label><br />";
  24. }
  25. }
  26. }
  27. echo "</td></tr>";
  28. }
  29. echo "\n</table>";
  30.  
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.