Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] - Działanie foreach
Forum PHP.pl > Forum > Przedszkole
Adi32
Witajcie.

Myślę, że jest coś prostego co mnie pominęło dlatego wybrałem przedszkole.

Mam taką tablicę:

  1. [1] => Array
  2. (
  3. [id] => 1
  4. [nazwa] => sklep
  5. [tytul_menu] => Sklep
  6. [tytul_tresc] => Sklep
  7. [tytul_stopka] => Sklep
  8. [tresc] => Witaj w naszym sklepie
  9. [id_parent] => 0
  10. [data_dodania] => 2012-04-17 10:36:34
  11. [status] => 1
  12. [pozycja] => 0
  13. [data_oststniej_edycji] => 2012-04-17 10:36:44
  14. [usuniety] => 0
  15. [url] => kategoria/1
  16. [uzytkownik_utworzyl] => admin
  17. [specialne] => freeline
  18. [lvl] => 1
  19. [parent] => Array
  20. (
  21. [id] => 2
  22. [nazwa] => podsklep
  23. [tytul_menu] => podSklep
  24. [tytul_tresc] => podSklep
  25. [tytul_stopka] => podSklep
  26. [tresc] => podWitaj w naszym sklepie
  27. [id_parent] => 1
  28. [data_dodania] => 2012-04-17 10:36:34
  29. [status] => 1
  30. [pozycja] => 0
  31. [data_oststniej_edycji] => 2012-04-17 10:36:44
  32. [usuniety] => 0
  33. [url] => kategoria/1
  34. [uzytkownik_utworzyl] => admin
  35. [specialne] => freeline
  36. [lvl] => 2
  37. [parent] => Array
  38. (
  39. [id] => 3
  40. [nazwa] => podsklep
  41. [tytul_menu] => podSklep
  42. [tytul_tresc] => podSklep
  43. [tytul_stopka] => podSklep
  44. [tresc] => podWitaj w naszym sklepie
  45. [id_parent] => 2
  46. [data_dodania] => 2012-04-17 10:36:34
  47. [status] => 1
  48. [pozycja] => 0
  49. [data_oststniej_edycji] => 2012-04-17 10:36:44
  50. [usuniety] => 0
  51. [url] => kategoria/1
  52. [uzytkownik_utworzyl] => admin
  53. [specialne] => freeline
  54. [lvl] => 3
  55. [parent] => Array
  56. (
  57. [id] => 4
  58. [nazwa] => podsklep
  59. [tytul_menu] => podSklep
  60. [tytul_tresc] => podSklep
  61. [tytul_stopka] => podSklep
  62. [tresc] => podWitaj w naszym sklepie
  63. [id_parent] => 3
  64. [data_dodania] => 2012-04-17 10:36:34
  65. [status] => 1
  66. [pozycja] => 0
  67. [data_oststniej_edycji] => 2012-04-17 10:36:44
  68. [usuniety] => 0
  69. [url] => kategoria/1
  70. [uzytkownik_utworzyl] => admin
  71. [specialne] => freeline
  72. [lvl] => 4
  73. )
  74.  
  75. )
  76.  
  77. )
  78.  
  79. )
  80.  
  81. [5] => Array
  82. (
  83. [id] => 5
  84. [nazwa] => sklep
  85. [tytul_menu] => Sklep
  86. [tytul_tresc] => Sklep
  87. [tytul_stopka] => Sklep
  88. [tresc] => Witaj w naszym sklepie
  89. [id_parent] => 0
  90. [data_dodania] => 2012-04-17 10:36:34
  91. [status] => 1
  92. [pozycja] => 0
  93. [data_oststniej_edycji] => 2012-04-17 10:36:44
  94. [usuniety] => 0
  95. [url] => kategoria/1
  96. [uzytkownik_utworzyl] => admin
  97. [specialne] => freeline
  98. [lvl] => 1
  99. [parent] => Array
  100. (
  101. [id] => 6
  102. [nazwa] => sklep
  103. [tytul_menu] => Sklep
  104. [tytul_tresc] => Sklep
  105. [tytul_stopka] => Sklep
  106. [tresc] => Witaj w naszym sklepie
  107. [id_parent] => 5
  108. [data_dodania] => 2012-04-17 10:36:34
  109. [status] => 1
  110. [pozycja] => 0
  111. [data_oststniej_edycji] => 2012-04-17 10:36:44
  112. [usuniety] => 0
  113. [url] => kategoria/1
  114. [uzytkownik_utworzyl] => admin
  115. [specialne] => freeline
  116. [lvl] => 2
  117. )
  118.  
  119. )
  120.  
  121. )


I pomyślałem - czy nie dałoby się tego jednym foreachem przelecieć...

  1. foreach ($oView->elementy as &$element) {
  2.  
  3. echo 'Id elementu: '.$element['id'].' Lev: '.$element['lvl'].'<br />';
  4.  
  5. if ($element['parent']) {
  6. $oView->elementy[$element['parent']['id']] = $element['parent'];
  7. }
  8.  
  9. }
  10. // zgadza się, zamiast parent powinno być child...


Wyniki tego foreacha nie mogę wyjaśnić w żaden logiczny sposób...

  1. Id elementu: 1 Lev: 1
  2. Id elementu: 5 Lev: 1
  3. Id elementu: 2 Lev: 2
  4. Id elementu: 6 Lev: 2
  5. Id elementu: 3 Lev: 3


Wiecie może dlaczego tak?
mortus
Jednym foreachem da się tylko wtedy, gdy użyjesz funkcji rekurencyjnej. To co natomiast robisz w pętli foreach, a konkretniej w warunku if, to dynamiczne wyciąganie "podtablic" do tablicy głównej, w związku z czym tablica rośnie, aż do czasu gdy dany element nie będzie miał potomków. Interpreatacja dla id = 1:
  1. if ($element['parent']) { // jeśli jest $element['parent']
  2. $oView->elementy[$element['parent']['id']] = $element['parent']; // to niech $oView->elementy[$element['parent']['id']], czyli $oView->elementy[2] będzie równy podtablicy $element['parent']
  3. }
Adi32
Cytat(mortus @ 17.04.2012, 16:04:16 ) *
Jednym foreachem da się tylko wtedy, gdy użyjesz funkcji rekurencyjnej. To co natomiast robisz w pętli foreach, a konkretniej w warunku if, to dynamiczne wyciąganie "podtablic" do tablicy głównej, w związku z czym tablica rośnie, aż do czasu gdy dany element nie będzie miał potomków. Interpreatacja dla id = 1:
  1. if ($element['parent']) { // jeśli jest $element['parent']
  2. $oView->elementy[$element['parent']['id']] = $element['parent']; // to niech $oView->elementy[$element['parent']['id']], czyli $oView->elementy[2] będzie równy podtablicy $element['parent']
  3. }


Zgadza się, wszystko się zgadza - tablica rośnie ale nie wyświetlają się wszystkie "podtablice" i w dziwnej kolejności. Zdaje się, że zrozumiałem już logikę takiego działania. Uzyskałem już żądany efekt bez użycia rekurencji, teraz chce porównać szybkość wykonania takiego działania z wykorzystaniem rekurencji i bez.

Jeszcze takie pytanko - jak najlepiej sprawdzać szybkość wykonania jakichś akcji?

Ja robie to tak:

  1. $start = microtime(true);
  2.  
  3. // jakieś akcje
  4.  
  5. echo 'Czas wykonania: '.microtime(true) - $start;


Ale wolałbym uzystać wynik w milisekundach.
mortus
Pomiar w mikrosekundach jest dokładniejszy niż w milisekundach, jeśli jednak potrzebujesz milisekund, to przemnóż wartości jakie da microtime() przez 1000. Zrozumiałem Twoje intencje i w ocenie wydajności rozwiązania pod uwagę musisz wziąć nie tylko czas wykonania, ale również zasobożerność, tj. ilość pamięci operacyjnej potrzebnej do wykonania pętli foreach czy też funkcji rekurencyjnej. No i pamiętaj o tym, że tablica "rośnie", przy czym dane w niej się powtarzają (no chyba, że to zmieniłeś), co raczej nie jest porządanym efektem.
Adi32
Dziękuje mortus, Twoje posty bardzo mi pomogły.

Jeszcze dopytam - jak porównywać zasobożerność kodu?
mortus
Możesz posłużyć się zewnętrznym profilerem, jak xdebug lub też skorzystać z funkcji jakie daje wersaj 5.2.0 PHP, tj. memory_get_peak_usege() lub też bardziej odpowiedniej w tym miejscu memory_get_usage() (przykład działania).
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.