Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Synchronizacja tablic. Identyczne klucze w każdej z tablic?
Forum PHP.pl > Forum > Przedszkole
kukix
Witam..

Posiadam dynamicznie generowane tablice, $dane[0], $dane[1], $dane[2] itd. Ilośc tablic to od 2 do max 5, średnia ilość kluczy w tych tablicach to 10-50 kluczy.

Potrzebuje zsynchronizować klucze w tych tablicach. tzn jeżeli w jednej tabeli występuje dany klucz to potrzebuje, żeby dodać go do pozostałych, które go nie posiadają, ale żeby wartość była pusta lub jakiś inny wybrany znak.

Znalazłem w manualu funkcje array_diff, jednak nie mam pomysłu jak optymalnie to wykorzystać.

Przykładowe tablice:
  1. $dane[0] = array (
  2. 'nazwa_1' => 'wartosc_1',
  3. 'nazwa_4' => 'wartosc_4'
  4. );
  5.  
  6. $dane[1] = array (
  7. 'nazwa_1' => 'wartosc_1a',
  8. 'nazwa_2' => 'wartosc_2a',
  9. 'nazwa_3' => 'wartosc_3a',
  10. 'nazwa_4' => 'wartosc_4a'
  11. 'nazwa_5' => 'wartosc_5a',
  12. 'nazwa_6' => 'wartosc_6a'
  13. );
  14.  
  15. $dane[2] = array (
  16. 'nazwa_2' => 'wartosc_2b',
  17. 'nazwa_3' => 'wartosc_3b',
  18. 'nazwa_4' => 'wartosc_4b'
  19. );
Niktoś
Ja bym to w taki sposób nie robił porównywanie każdej tablicy z każdą i przypisywanie unikalnych kluczy byłoby dość trudne w realizacji i nie wiem czy opcjonalne.
Proponuję utworzyć tablicę albo liste(lista daje chyba większe możliwości filtracji) i przypisać do niej wszystkie klucze z wszystkich tablic i usunąć duplikaty.
A potem:
$dane[0]=/przefiltrowana lista lub tablica/;
$dane[1]=/przefiltrowana lista lub tablica/;
$dane[2]=/przefiltrowana lista lub tablica/;
W ten sposób będziesz miał w każdej tablicy te same klucze.
Nie chce źle doradzić ale do łączenia tablic jest funkcja array_merge.Sam pomysł chyba jest dobry.
thek
Ale Tobie chodzi o klucze, a nie wartości, czyli musiałbyś użyć array_diff_key. Problem z tym, że skoro masz X tablic, to działań masz masę... Czemu? Ponieważ masz porównania wszystkich tablic między sobą. Przypuśćmy, że masz tablice A, B i C... To do tablicy A dodajesz klucze wynikające z różnic między C i A oraz C i B. Jednocześnie robisz to samo z B (C i B oraz A i B) oraz C (A i C oraz B i C). Co gorsze to muszą one w trakcie wszystkich operacji być niezmienne. To daje nam 6 operacji. Liczba ta rośnie według wzoru n!... czyli 5 tablic to 5! = 120 samych operacji array_diff_key.
A jak wyglądałby sam proces tym sposobem? Najprościej do wytłumaczenia chyba tak:
1. Wybierz tablicę.
2. Utwórz pustą.
3. Wykonaj array_diff_key innej oraz wybranej.
4. Połącz ją z tą utworzoną w punkcie 2.
5. Jeśli jest kolejna tablica - weź ją i idź do punktu 3
6. Jeśli nie ma, weź sobie wszystkie wartości tablicy z punktu 2 ustaw na takie jakie sygnalizują, że to nowy klucz
7. Dołącz tablicę bazową z punktu 1, a wynik to właśnie to jak wygląda ta tablica bazowa po zmianach.
8. Powtarzaj aż skończą Ci się tablice.

Uważaj... Nie możesz działać na referencjach, gdyż po pierwszej zmianie miałbyś już zafałszowaną tablicę bazową. Dla Twojego przykładu wyglądałby proces tak:
1. Weź $dane[0]
2. Utwórz pustą $wynik[0]
3. Zrób różnice dla $dane[1] diff $dane[0] (nazwa_2, nazwa_3, nazwa_5, nazwa_6) oraz $dane[2] diff $dane[0] (nazwa_2, nazwa_3)
4. Dostajemy tablicę $wynik[0] z kluczami (nazwa_2, nazwa_3, nazwa_5, nazwa_6) i ustawiamy im jakąś wartość charakterystyczną
5. Do tej tablicy dołączamy bazową.
6. Podobnie robimy z resztą.

EDIT: Niktoś, problem jest taki, że z ]array_merge trzeba uważać. Zobacz sobie jak ona się zachowuje przy kluczach numerycznych. Tu trzeba naprawdę dobrze "wyczuć". Pomysł z array_merge jest o wiele lepszy niż z array_diff_key, ale naprawdę trzeba uważać na klucze.
kukix
A co byście powiedzieli, żeby połączyć ze sobą wszystkie tablice.. array_merge() i tak utworzoną tablicę dopiero porównać array_diff_key() z tymi, którymi dysponuje?

Czy nie będzie szybsze i łatwiejsze?
Niktoś
Właśnie o tym myślałem.Innego sposobu na połączenie danych nie ma bo patrząc na array_merge to też mam wątpliwości?
O to chodzi ,żeby zrobić obraz wszystkich danych w tablicy.I tą jedną tablicę porównywać z każdą i uzupełniać klucze z pustymi wartościami tak jak autor by chciał.
thek
Masz klucze numeryczne - zapomnij o array_merge. Przy array_merge indeksy numeryczne zostają przeindeksowane :/ Zobacz sobie przykład 2 w manualu tej funkcji. Jeśli to klucze asocjacyjne - wal array_merge bez problemu, bo to będzie o wiele lepsze.

EDIT: Przy czym w przypadku array_merge, jeśli masz jedynie klucze asocjacyjne, możesz zapomnieć o diffie. Wystarczy, że tablicę bazową dołączysz jako ostatnią. array_merge ma taką fajną właściwość, że w takim wypadku nadpisze wartość.
Innymi słowy Twój algorytm dla array_merge wyglądałby tak:
1. Połącz wszystkie tablice inne niż wybrana
2. Ustaw wszystkim kluczom wybraną wartość.
3. Podłącz do tak otrzymanej - wybraną tablicę,

Możesz także jak proponujesz... Jedna tablica z wszystkim kluczami (tylko uważać na te klucze numeryczne!) i od razu ją jako wzorzec wyzerować. Potem tylko ją łączyć z kolejnymi. Jak widać metod jest wiele smile.gif To jest bowiem optymalizacja tego co podałem w poście tym.
Niktoś
Thek,ja się z tobą nie kłócę to był tylko propozycja,pomysł,ale mówisz ,że nie da rady to pewnie tak jest.Nie jestem aż tak doświadczony jak ty.To taki mój mały pomysł.
Edit.Poóźno już trza iść spać bo zaczynam bredzić wink.gif
thek
@Niktoś: Nie kłócę się z pomysłem. Zauważyłem jednak pewne miejsce, gdzie może wyniknąć problem z racji określonego zachowania array_merge. Dopóki są jedynie klucze nienumeryczne, nie będzie problemu. Jeśli będą, trzeba będzie innego rozwiązania poszukać, które jest niewrażliwe na tą przypadłość. Z przykładu wynika, że możesz mieć rację i array_merge wystarczy, ale to nam jedynie autor wątku może potwierdzić.
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.