Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Podwójne iterowanie po tablicy each()
Forum PHP.pl > Forum > PHP
Zick4
Mam menu rozwijane posiadające elementy oraz podelementy. U mnie $menu to obiekt klasy menu gdzie jest tablica elementów, a każdy element ma swoją tablicę podelementów. Obie tablice (elementów i podelementów) są indeksowane numerycznie. Jeżeli usuwam jakiś element bądz podelement unsetuje go. Przez to tworzy się tablica z dziurami. Poniższy przykład jest tylko oglądowy co chcę pokazać, bo tak naprawdę to są obiekty bardziej skomplikowane, które mają swoje właściwości i metody.
  1. <?php
  2. 0=>array(0=>'a', 1=>'b', 2=>'c'),
  3. 1=>array(0=>'a', 1=>'b', 2=>'c'),
  4. 2=>array(0=>'a', 1=>'b', 2=>'c')
  5. );
  6. ?>

Jeżeli teraz usunę element o indeksie 1 to pozostanie mi
  1. <?php
  2. 0=>array(0=>'a', 1=>'b', 2=>'c'),
  3. 2=>array(0=>'a', 1=>'b', 2=>'c')
  4. );
  5. ?>

i teraz jeszcze usunę podelement pierwszej tablicy o indeksie 1 to
  1. <?php
  2. 0=>array(0=>'a', 2=>'c'),
  3. 2=>array(0=>'a', 1=>'b', 2=>'c')
  4. );
  5. ?>

co mi bardzo nie odpowiada, bo zostają dziury więc napisałem funkcję porządkującą, która nie działa, bo według mnie resetowanie nie jest dobrze zrobione. Np. jeżeli zmodyfukiję trochę poniższą funkcję i zrobię tylko jedną pętle np. dla samym elementów, bądź dla samych podelementów to działa, ale jeżeli chcę zrobić obie i przejść przez wszystko to dochodzi tylko do pierwszego elementu zagłębia się do podelementów poprawia je ale już nie przechodzi do następnego elementu.
  1. <?php
  2. function uporzadkujMenu($menu)
  3. {
  4. reset ($menu->elementy);
  5. $tab = array();
  6. for ($index = 0; list ($klucz, $wartosc) = each($menu->elementy); $index++)
  7. {
  8. $tab[$index] = $wartosc;
  9. reset($tab[$index]->podelementy);
  10.  
  11. $tab2 = array();
  12. for ($i = 0; list ($klucz2, $wartosc2) = each($tab[$index]->podelementy); $i++)
  13. {
  14.  $tab2[$i] = $wartosc2;
  15. }
  16. $tab[$index] = $tab2;
  17. }
  18.  
  19. $menu->elementy = $tab;
  20. return $menu;
  21. }
  22. ?>

Jakieś pomysły?
phpion
Użyj foreach zamiast for lub w for'ze sprawdzaj czy dany index istnieje (isset()).
krowal
A tak właściwie to czemu Ci te dziury przeszkadzają, przecież tak czy owak kolejność jest nadal zachowana. Podejrzewam, że wyświetlanie tego zrobiłeś w jakiś dziwny sposób, zamiast użyć normalnie foreach dla każdego z elementów i podelementów ? No chyba że sztuka dla sztuki smile.gif
Zick4
Zrobiłem tak ponieważ mam funkcję
  1. <?php
  2. function znajdzElement($nazwa_elementu) //dostaję stringa i jeżeli znalazłem to zwracam index
  3. {
  4. $index = 0;
  5. foreach ($this->podelementy as $a)
  6. {
  7. if ($a->nazwa == $nazwa_elementu)
  8. {
  9. return $index;
  10. }
  11. $index++;
  12. }
  13. return false;
  14. }
  15. ?>

Bez uporządkowania zwraca zły index.To był pierwszy powód, a drugi to mam funkcję dodajElement()
  1. <?php
  2. function dodajPodElement($nazwa)
  3. {
  4. $nowy_podelement = new PodElementMenu($nazwa);
  5. $this->podelementy[] = $nowy_podelement;
  6. }
  7. ?>

Bez uporządkowania dodaje elementy w róznym miejscu raz za tym elementem a raz za innym. A ja bym chciał na końcu. (hmm można by chyba dać array.pusha() i to chyba dodał by na końcu). Oto moja klasa menu
  1. <?php
  2. class Menu
  3. {
  4. public $nazwa;
  5. public $elementy = array();
  6. function __construct($nazwa_menu)
  7. {
  8. $this->nazwa = $nazwa_menu;
  9. }
  10. function dodajElement($nazwa)
  11. {
  12. $nowy_element = new ElementMenu($nazwa);
  13. $this->elementy[] = $nowy_element;
  14.  
  15. }
  16.  
  17.  
  18. function znajdzElement($element)
  19. {
  20. $index = 0;
  21. foreach ($this->elementy as $a)
  22. {
  23. if ($a->nazwa == $element)
  24. {
  25. return $index;
  26. }
  27. $index++;
  28. }
  29. return false;
  30. }
  31. }
  32.  
  33. class ElementMenu extends PodElementMenu
  34. {
  35. public $nazwa;
  36. public $sciezka;
  37. public $podelementy = array();
  38. function __construct($nazwa_elementu, $sciezka_do_elementu=null)
  39. {
  40. $this->nazwa = $nazwa_elementu;
  41. $this->sciezka = $sciezka_do_elementu;
  42. }
  43. function edytuj($nazwa_elementu, $sciezka_do_elementu=null)
  44. {
  45. $this->nazwa = $nazwa_elementu;
  46. if ($sciezka_do_elementu != null)
  47.  $this->sciezka = $sciezka_do_elementu;
  48. }
  49. function dodajPodElement($nazwa)
  50. {
  51. $nowy_podelement = new PodElementMenu($nazwa);
  52. $this->podelementy[] = $nowy_podelement;
  53. }
  54.  
  55. //funkcja dostaje stringa i szuka podelementu o takiej nazwie
  56. function znajdzPodElement($nazwa_elementu)
  57. {
  58. $index = 0;
  59. foreach ($this->podelementy as $a)
  60. {
  61. if ($a->nazwa == $nazwa_elementu)
  62. {
  63. return $index;
  64. }
  65. $index++;
  66. }
  67. return false;
  68. }
  69. }
  70. ?>
jang
  1. <?php
  2. $menu = array(
  3. 0=>array(0=>'a', 1=>'b', 2=>'c'),
  4. 2=>array(0=>'a', 2=>'c'),
  5. 5=>array(1=>'a', 3=>'b', 7=>'c'),
  6. );
  7. var_export ($menu);
  8. echo '<br /><br />';
  9.  
  10. function uporzadkujMenu($menu)
  11. {
  12. $tab = array();
  13. for ($index = 0; list ($klucz, $wartosc) = each($menu); $index++)
  14. {
  15. $tab[$index] = $wartosc;
  16.  
  17. $tab2 = array();
  18. for ($i = 0; list ($klucz2, $wartosc2) = each($tab[$index]); $i++)
  19. {
  20.  $tab2[$i] = $wartosc2;
  21. }
  22. $tab[$index] = $tab2;
  23. }
  24.  
  25. $menu = $tab;
  26. return $menu;
  27. }
  28.  
  29. $menu = uporzadkujMenu($menu);
  30. var_export ($menu);
  31. ?>

Wynik:
  1. array ( 0 => array ( 0 => 'a', 1 => 'b', 2 => 'c', ), 2 => array ( 0 => 'a', 2 => 'c', ), 5 => array ( 1 => 'a', 3 => 'b', 7 => 'c', ), )
  2.  
  3. array ( 0 => array ( 0 => 'a', 1 => 'b', 2 => 'c', ), 1 => array ( 0 => 'a', 1 => 'c', ), 2 => array ( 0 => 'a', 1 => 'b', 2 => 'c', ), )
Zick4
Cytat(Zick4 @ 15.11.2007, 09:13:00 ) *
Bez uporządkowania dodaje elementy w róznym miejscu raz za tym elementem a raz za innym. A ja bym chciał na końcu. (hmm można by chyba dać array.pusha() i to chyba dodał by na końcu). Oto moja klasa menu

Sprawdziłem i jednak bzdury gadam bo i pushem i $tab[] dodaje na końcu smile.gif
Cytat(Zick4 @ 15.11.2007, 09:13:00 ) *
Bez uporządkowania zwraca zły index.To był pierwszy powód, a drugi to mam funkcję dodajElement()
  1. <?php
  2. function znajdzElement($element)
  3. {
  4. $index = 0;
  5. foreach ($this->elementy as $a)
  6. {
  7. if ($a->nazwa == $element)
  8. {
  9. return $index;
  10. }
  11. $index++;
  12. }
  13. return false;
  14. }
  15. ?>

Zmieniłem na
  1. <?php
  2. function znajdzElement($element)
  3. {
  4.  
  5. while (list ($klucz, $wartosc) = each($this->elementy))
  6. if ($wartosc->nazwa == $element)
  7. return $klucz;
  8. return false;
  9. }
  10. ?>

i teraz działa zwracanie dobrego indeksu. Teraz tak tylko z ciekawości się zastanawiam, jak zrobić aby iterować po tablicy wielowymiarowej z użyciej each

Jang świetnie, że Ci chodzi. Mi niestety nie. Narazie mam usuwanie bez uporządkowania , ale warto coś z tym zrobić więc jeszcze podrążę temat. Moja klasa:
  1. <?php
  2. class Menu
  3. {
  4. public $elementy = array(); //w środku obiekty klasy ElementMenu
  5. ...
  6. }
  7. class ElementMenu extends ElementPodMenu
  8. {
  9. public $podelementy = array();//w środku obiekty klasy PodElementMenu
  10. ...
  11. }
  12. class ElementPodMenu
  13. {
  14. ...
  15. }
  16. ?>


I dałem do nich taką funkcję, która nie działa
  1. <?php
  2. function uporzadkujMenu(&$menu)
  3. {
  4. $elementy = array();
  5. for ($index = 0; list ($klucz, $wartosc) = each($menu->elementy); $index++)
  6. {
  7. $elementy[$index] = $wartosc;
  8. $podelementy = array();
  9. for ($i = 0; list ($klucz2, $wartosc2) = each($elementy[$index]->podelementy); $i++)
  10. {
  11.  $podelementy[$i] = $wartosc2;
  12. }
  13. $elementy[$index]->podelementy = $podelementy;
  14. }
  15. $menu->elementy = $elementy;
  16. }
  17. uporzadkujMenu($menu);
  18. ?>
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.