Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Tablica wielowymiarowa
Forum PHP.pl > Forum > PHP
heniek87
Witam!
Mam tu tablicę wielowymiarową
  1. $arr = array(
  2. 1 => array(
  3. 1 => '1.1',
  4. 2 => array(
  5. 1 => 'tekst przed',
  6. 2 => array(
  7. 1 => '1.2.2.1',
  8. 2 => 8
  9. ),
  10. 3 => array(
  11. "cos" => '1.2.3',
  12. 2 => "cos innego",
  13. 3 => 8
  14. )
  15. )
  16. ),
  17. 2 => array(
  18. 1 => '2.1',
  19. 2 => 6
  20. ),
  21. 3 => array(
  22. 1 => '3.1',
  23. 2 => array(
  24. "cos" => '3.2.1',
  25. 2 => 9,
  26. 3 => 8
  27. )
  28. )
  29. );

Mój problem polega na tym że chciałbym odczytywać i edytować taką tablicę, lecz nie sposobem:
  1. echo $arr[1][2][1];
  2. $arr[1][2][1]='tekst po';

lecz;
mając zmienną np;
  1. $sciezka="1.2.1";
  2. $arr[$sciezka]='tekst po'; //powinno się odnosić do $arr[1][2][1];
  3. //oczywiście powyższy fragment kodu nie będzie działał

z odczytem sobie poradziłem, gorzej z zapisem w określonym miejscu.
Porszę o pomoc
Navyman
Ja wiem, że prosisz o pomoc i zaleci spamem, ale muszę zapytać... PO CO?

Masz tu fragment manuala: http://php.net/manual/en/language.variables.variable.php
Z tego zrobisz co chcesz. ALE PO CO? biggrin.gif
heniek87
Niestety w manualu nie znalazłem rozwiązania
  1. $k='arr[1][2][1]';
  2. $$k='tekst po';

nie zadziała
wizu
Najwygodniej będzie ci to zrobić obudowując tablicę klasą implementującą interfejs ArrayAcces, prosta i ładna smile.gif implementacja na szybko, powinna działać:
  1. class ArrayTest implements ArrayAccess
  2. {
  3. private $array;
  4.  
  5. public function __construct(&$array)
  6. {
  7. $this->array = $array;
  8. }
  9.  
  10. public function offsetUnset($offset)
  11. {
  12. //unset
  13. }
  14.  
  15. public function offsetSet($offset, $value)
  16. {
  17. $parts = explode('.', $offset);
  18. $tab = &$this->array;
  19. foreach($parts as $part)
  20. if(isset($tab[$part]))
  21. $tab = &$tab[$part];
  22. else
  23. break;
  24. $tab = $value;
  25. }
  26.  
  27. public function offsetGet($offset)
  28. {
  29. $parts = explode('.', $offset);
  30. $tab = &$this->array;
  31. foreach($parts as $part)
  32. if(isset($tab[$part]))
  33. $tab = $tab[$part];
  34. else
  35. break;
  36.  
  37. return $tab;
  38. }
  39.  
  40. public function offsetExists($offset)
  41. {
  42. // isset
  43. }
  44. }
  45.  
  46.  
  47. $array = array(
  48. array(1, 2, array(3, 4, array(5, 6))),
  49. array(7, 8, array(9, 10, array(11, 12)))
  50. );
  51.  
  52. $interArray = new ArrayTest($array);
  53. echo $interArray['1.2.2.0'], '<br />';
  54. $interArray['1.2.2.0'] = 15;
  55. echo $interArray['1.2.2.0'];
heniek87
Cytat(wizu @ 20.09.2011, 12:58:55 ) *
Najwygodniej będzie ci to zrobić obudowując tablicę klasą implementującą interfejs ArrayAcces, prosta i ładna smile.gif implementacja na szybko, powinna działać:
  1. class ArrayTest implements ArrayAccess
  2. {
  3. private $array;
  4.  
  5. public function __construct(&$array)
  6. {
  7. $this->array = $array;
  8. }
  9.  
  10. public function offsetUnset($offset)
  11. {
  12. //unset
  13. }
  14.  
  15. public function offsetSet($offset, $value)
  16. {
  17. $parts = explode('.', $offset);
  18. $tab = &$this->array;
  19. foreach($parts as $part)
  20. if(isset($tab[$part]))
  21. $tab = &$tab[$part];
  22. else
  23. break;
  24. $tab = $value;
  25. }
  26.  
  27. public function offsetGet($offset)
  28. {
  29. $parts = explode('.', $offset);
  30. $tab = &$this->array;
  31. foreach($parts as $part)
  32. if(isset($tab[$part]))
  33. $tab = $tab[$part];
  34. else
  35. break;
  36.  
  37. return $tab;
  38. }
  39.  
  40. public function offsetExists($offset)
  41. {
  42. // isset
  43. }
  44. }
  45.  
  46.  
  47. $array = array(
  48. array(1, 2, array(3, 4, array(5, 6))),
  49. array(7, 8, array(9, 10, array(11, 12)))
  50. );
  51.  
  52. $interArray = new ArrayTest($array);
  53. echo $interArray['1.2.2.0'], '<br />';
  54. $interArray['1.2.2.0'] = 15;
  55. echo $interArray['1.2.2.0'];

Wiedziałem że będę musiał obiekty robić, raczkuje w tym jeszcze. W tym gotowcu co podałeś jak załączę swoją tablicę to przy zmianie wartości wywala mi błąd

Fatal error: Cannot create references to/from string offsets nor overloaded objects in /********/test.php on line 22

w twoim przykładzie jest to 21 wers
wizu
Pewnie za głęboko szukasz (tzn pozycja którą przechodzisz jest stringiem, a nie tablicą).
Podałem Ci bazową implementację, musisz ją sobie sam rozbudować, żeby była odporna na tego typu błędy wink.gif

Powodzenia.
bastard13
Ja osobiście skłoniłbym się do przemyślenia problemu jeszcze raz i nie opakowywałbym takiej tablicy w obiekt, a raczej zamieniłbym twoją tablicę na grupy powiązanych obiektów. Tablica z takim poziomem zagnieżdżenia z pewnością może zostać rozbita i przepisana w coś bardziej funkcjonalnego i przyjemniejszego dla oka.
heniek87
Cytat(wizu @ 20.09.2011, 13:20:55 ) *
Pewnie za głęboko szukasz (tzn pozycja którą przechodzisz jest stringiem, a nie tablicą).
Podałem Ci bazową implementację, musisz ją sobie sam rozbudować, żeby była odporna na tego typu błędy wink.gif

Powodzenia.

Niestety czy podam ścieżkę do stringu czy do tablicy to wywala ten sam błąd, chyba nie dam rady tego naprawić

Cytat(bastard13 @ 20.09.2011, 13:21:20 ) *
Ja osobiście skłoniłbym się do przemyślenia problemu jeszcze raz i nie opakowywałbym takiej tablicy w obiekt, a raczej zamieniłbym twoją tablicę na grupy powiązanych obiektów. Tablica z takim poziomem zagnieżdżenia z pewnością może zostać rozbita i przepisana w coś bardziej funkcjonalnego i przyjemniejszego dla oka.

Mój problem polega na tym że nie umiem jeszcze operować na obiektach. Jeszcze nigdy nie miałem takiego problemu żeby na forum pisać tongue.gif
moja tablica opiera sie na pliku typu json i właśnie tam chciałbym zostawić wszystkie dane a tablica musi być miesz na i może osiągnąć nawet 50 wymiarów

ta tablica może osiągnąć nawet 50 wymiarów i przechowuje ją w json'ie i musi być mieszana stąd taki problem
bastard13
Cytat(heniek87 @ 20.09.2011, 13:35:18 ) *
Mój problem polega na tym że nie umiem jeszcze operować na obiektach.

Zawsze musi być ten pierwszy raz:D A im szybciej tym lepiej:D

Cytat(heniek87 @ 20.09.2011, 13:35:18 ) *
może osiągnąć nawet 50 wymiarów

W takim wypadku, jeżeli chcesz to zrobić dobrze i żeby po x okresie czasu nikt (bądź ty sam:) nie musiał na Ciebie bluzgać, to powinno być zmienione.
heniek87
Cytat(bastard13 @ 20.09.2011, 13:39:08 ) *
Zawsze musi być ten pierwszy raz:D A im szybciej tym lepiej:D


W takim wypadku, jeżeli chcesz to zrobić dobrze i żeby po x okresie czasu nikt (bądź ty sam:) nie musiał na Ciebie bluzgać, to powinno być zmienione.

Nie mogę tego zmienić, gdyż musi to być bardzo mocno rozbudowana baza, a w moim przypadku im większa tym lepiej
bastard13
Rozbudowana baza to nie jest coś co wyklucza zmiany bądź stosowanie obiektów. Właściwie, to jeżeli jest bardzo rozbudowana baza, to te obiekty ułatwiają później zrozumienie logiki działania całej aplikacji. Oczywiście przeprowadzenie takiej operacji na żywym organizmie jest trudniejsze, ale to już twoja decyzja:)
heniek87
Cytat(bastard13 @ 20.09.2011, 14:18:05 ) *
Rozbudowana baza to nie jest coś co wyklucza zmiany bądź stosowanie obiektów. Właściwie, to jeżeli jest bardzo rozbudowana baza, to te obiekty ułatwiają później zrozumienie logiki działania całej aplikacji. Oczywiście przeprowadzenie takiej operacji na żywym organizmie jest trudniejsze, ale to już twoja decyzja:)

jeszcze nie jest to żywy organizm. Czy mógłbyś troszkę bardziej mnie oświecić w jaki sposób mógłby przebudować to ?
bastard13
Cytat(heniek87 @ 20.09.2011, 14:20:29 ) *
Czy mógłbyś troszkę bardziej mnie oświecić w jaki sposób mógłby przebudować to ?

Bez znajomości logiki tzn. tego, co tam się dzieje i dlaczego takie próby 'oświecenia' to raczej spełzną na niczym:)
heniek87
Chcę zrobić kreator misji tzn. piszę opis sytuacji i daje kilka opcji do wyboru. Po wypostowaniu tego musi się to znaleźć w tablicy. Następnie klikam na jedną z opcji którą wcześniej dodałem i znów piszę ospis sytuacji i dodaje kilka opcji itd..
phpion
Wyjęte z Kohany 2.3.4:
  1. /**
  2. * Returns the value of a key, defined by a 'dot-noted' string, from an array.
  3. *
  4. * @param array array to search
  5. * @param string dot-noted string: foo.bar.baz
  6. * @return string if the key is found
  7. * @return void if the key is not found
  8. */
  9. public static function key_string($array, $keys)
  10. {
  11. if (empty($array))
  12. return NULL;
  13.  
  14. // Prepare for loop
  15. $keys = explode('.', $keys);
  16.  
  17. do
  18. {
  19. // Get the next key
  20. $key = array_shift($keys);
  21.  
  22. if (isset($array[$key]))
  23. {
  24. if (is_array($array[$key]) AND ! empty($keys))
  25. {
  26. // Dig down to prepare the next loop
  27. $array = $array[$key];
  28. }
  29. else
  30. {
  31. // Requested key was found
  32. return $array[$key];
  33. }
  34. }
  35. else
  36. {
  37. // Requested key is not set
  38. break;
  39. }
  40. }
  41. while ( ! empty($keys));
  42.  
  43. return NULL;
  44. }
bastard13
Cytat(heniek87 @ 20.09.2011, 14:45:34 ) *
Chcę zrobić kreator misji tzn. piszę opis sytuacji i daje kilka opcji do wyboru. Po wypostowaniu tego musi się to znaleźć w tablicy. Następnie klikam na jedną z opcji którą wcześniej dodałem i znów piszę ospis sytuacji i dodaje kilka opcji itd..

Czyli rozumiem, że robisz coś takiego (muszę sobie to łopatologicznie przedstawić dla lepszego zrozumienia:):
- tworzę misję UratujMisia, dodaję opis: 'Pomóż Ani uratować misia z rąk złej, brzydkiej czarownicy'. I dodaję opcje: SzukajMisiaWZamku, SzukajWLochach, SzukajWPokojuAni
- następnie biorę opcję SzukajMisiaWZamku, dodaję opis: 'Przeszukaj cały zamek, wszystkie komnaty i wypytaj ludzi, czy nie widzieli misia'. Dodaję opcje: SzukajWKomnacieKrólewskiej, SzukajWJadalni etc.
i oczywiście te kroki powtarzamy zagłębiając się jeszcze głębiej.
O to chodzi?
Jak nie, to rzuć przykładem, jeżeli tak, to twoim rozwiązaniem jest:
Composite lub po polsku.
heniek87
Cytat(bastard13 @ 21.09.2011, 10:32:33 ) *
Czyli rozumiem, że robisz coś takiego (muszę sobie to łopatologicznie przedstawić dla lepszego zrozumienia:):
- tworzę misję UratujMisia, dodaję opis: 'Pomóż Ani uratować misia z rąk złej, brzydkiej czarownicy'. I dodaję opcje: SzukajMisiaWZamku, SzukajWLochach, SzukajWPokojuAni
- następnie biorę opcję SzukajMisiaWZamku, dodaję opis: 'Przeszukaj cały zamek, wszystkie komnaty i wypytaj ludzi, czy nie widzieli misia'. Dodaję opcje: SzukajWKomnacieKrólewskiej, SzukajWJadalni etc.
i oczywiście te kroki powtarzamy zagłębiając się jeszcze głębiej.
O to chodzi?
Jak nie, to rzuć przykładem, jeżeli tak, to twoim rozwiązaniem jest:
Composite lub po polsku.

Tak, dokładnie o to mi chodzi, przeszukałem google i niestety głównie wzorce są dla jawy i trochę tego nie ogarniam, ale posiedzę trochę nad tym bo teraz już wiem przynajmniej czego szukam. Nie ukrywam że wolałbym sam napisać ten skrypt brakuje mi tylko zapisu nowych danych do aplikacji. Dzięki za pomoc. Pozdrawiam.
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.