Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Porównywanie tablic
Forum PHP.pl > Forum > PHP
foxbond
  1. <?php
  2. $ar1 = array();
  3. $ar1[] = array("id"=>1, "nick"=>"zostal","log"=>"zostal"); //poprzedni gracze
  4. $ar1[] = array("id"=>2, "nick"=>"odszedl","log"=>"odszedl");
  5. $ar2 = array();
  6. $ar2[] = array("id"=>1, "nick"=>"zostal","log"=>"zostal"); //obecni gracze
  7. $ar2[] = array("id"=>3, "nick"=>"doszedl","log"=>"doszedl");
  8. $pozostali = array();
  9.  
  10. for ($i=0; $i<count($ar1); $i++){
  11. for($ii=0; $ii<count($ar2); $ii++){
  12. if ($ar1[$i]['id'] == $ar2[$ii]['id']){
  13. $pozostali[] = $ar2[$ii];
  14. }
  15. }
  16. }
  17. echo "\r\nOdeszli:";
  18. var_dump(array_diff($ar1, $ar2));//zla wartosc
  19.  
  20. echo "\r\nDoszli:";
  21. var_dump(array_diff($ar2, $ar1));//zla wartosc
  22.  
  23. echo "\r\nPozostali:";
  24. var_dump(array_intersect($ar1, $ar2));//zla wartosc
  25. echo "\r\n Lub:";
  26. var_dump($pozostali);//dobry wynik
  27. ?>



Potrzebuję pobrać elementy które:
*są w pierwszej tablicy ale nie ma ich w drugiej
*są w drugiej tablicy ale nie ma ich w pierwszej
*są w obu tablicach (to już mam)

mar1aczi
array_diff
foxbond
Właśnie skorzystałem z tej funkcji (array_diff) jednak nie zwraca ona prawidłowego wyniku.

Z tego co wyczytałem przyrównuje ona na zasadzie
Kod
(string)ob1 === (string)obj2


Wiec poszukuję innego sposobu, gdyż w moim wypadku funkcja ta nic nie zwraca
mar1aczi
Może pętla i funkcja in_array, jeśli elementy powtarzające się są identyczne co do klucza i wartości.
foxbond
Znów powtórzę, znajdywanie wspólnych elementów działa (właśnie poprzez pętlę) nie mogę natomiast uzyskać jakie elementy są w pierwszej tablicy, a nie ma ich w drugiej oraz na odwrót
_Borys_
array_diff() powinno działać, wyszukuje w pierwszej tablicy tego czego nie ma w drugiej. Jeśli ma wyszukać odwrotnie różnice to zamieniamy tablice miejscami.
foxbond
  1. <?php
  2.  
  3. $ar1 = array();
  4. $ar1[] = array("id"=>1, "nick"=>"zostal","log"=>"zostal"); //poprzedni gracze
  5. $ar1[] = array("id"=>2, "nick"=>"odszedl","log"=>"odszedl");
  6. $ar1[] = array("id"=>4, "nick"=>"odszedl2","log"=>"odszedl2");
  7. $ar1[] = array("id"=>6, "nick"=>"zostal2","log"=>"zostal2"); //poprzedni gracze
  8. $ar2 = array();
  9. $ar2[] = array("id"=>1, "nick"=>"zostal","log"=>"zostal"); //obecni gracze
  10. $ar2[] = array("id"=>3, "nick"=>"doszedl","log"=>"doszedl");
  11. $ar2[] = array("id"=>5, "nick"=>"doszedl2","log"=>"doszedl2");
  12. $ar2[] = array("id"=>6, "nick"=>"zostal2","log"=>"zostal2"); //obecni gracze
  13. $ar2[] = array("id"=>9, "nick"=>"doszedl3","log"=>"doszed3");
  14. $pozostali = array();
  15. $odeszli = array();
  16. $doszli = array();
  17.  
  18. for ($i=0; $i<count($ar1); $i++){
  19. for($ii=0; $ii<count($ar2); $ii++){
  20. if ($ar1[$i]['id'] == $ar2[$ii]['id']){
  21. $pozostali[] = $ar2[$ii];
  22. }
  23. }
  24. }
  25. /////
  26.  
  27. for ($i=0; $i<count($ar1); $i++){
  28. $che = false;
  29. for($ii=0; $ii<count($ar2); $ii++){
  30.  
  31. if ($ar1[$i]['id'] == $ar2[$ii]['id']){
  32. $che=true;
  33. }
  34. }
  35. if (!$che){
  36. $odeszli[] = $ar1[$i];
  37. }
  38. }
  39.  
  40. for ($i=0; $i<count($ar2); $i++){
  41. $che = false;
  42. for($ii=0; $ii<count($ar1); $ii++){
  43.  
  44. if ($ar2[$i]['id'] == $ar1[$ii]['id']){
  45. $che=true;
  46. }
  47. }
  48. if (!$che){
  49. $doszli[] = $ar2[$i];
  50. }
  51. }
  52.  
  53.  
  54.  
  55. echo "\r\nOdeszli:";
  56. var_dump(array_diff($ar1, $ar2));//zla wartosc
  57. echo "\r\n Lub:";
  58. var_dump($odeszli);//dobry wynik
  59.  
  60. echo "\r\nDoszli:";
  61. var_dump(array_diff($ar2, $ar1));//zla wartosc
  62. echo "\r\n Lub:";
  63. var_dump($doszli);//dobry wynik
  64.  
  65. echo "\r\nPozostali:";
  66. var_dump(array_intersect($ar1, $ar2));//zla wartosc
  67. echo "\r\n Lub:";
  68. var_dump($pozostali);//dobry wynik



Mam już rozwiązanie, jednak nie jest ono zbyt optymalne. Ta operacja będzie wykonywana co sekundę*liczba os. na stronie, a wielkość obu tablic będzie się wahać od 0 do 200 elementów

Tak więc zna ktoś inny sposób na rozwiązanie tego problemu?

Nawet policzyłem, to będzie 3.600.000 pętli for/min. Myślę, że jest to trochę za dużo dlatego proszę o porady jak to zoptymalizować
_Borys_
Może MYSQL będzie wydajniejsze, też można wyciągać różnice z tabel.
foxbond
Nie wiem czy będzie to odpowiednie rozwiązanie.

jedna tablica jest przechowywana w $_SESSION, druga za każdym razem pobierana z bazy.

Gdyby dwie tabele znajdywały się w bazie to mam zapytanie:
Kod
SELECT * FROM a WHERE a.id NOT IN (SELECT b.id FROM b );
i w druga strone
SELECT * FROM b WHERE b.id NOT IN (SELECT a.id FROM a);

(działające zresztą)


Może ktoś w przybliżeniu napisać jak to w takim razie zintegrować?
UPDATE obecnej tablicy przed każdą operacją odpada. To musi być jakaś hybryda (pętle w zapytaniu sql(?)
irmidjusz
  1. $ar1 = array();
  2. $ar1[] = array("id"=>1, "nick"=>"zostal","log"=>"zostal"); //poprzedni gracze
  3. $ar1[] = array("id"=>2, "nick"=>"odszedl","log"=>"odszedl");
  4. $ar1[] = array("id"=>4, "nick"=>"odszedl2","log"=>"odszedl2");
  5. $ar1[] = array("id"=>6, "nick"=>"zostal2","log"=>"zostal2"); //poprzedni gracze
  6.  
  7. $ar2 = array();
  8. $ar2[] = array("id"=>1, "nick"=>"zostal","log"=>"zostal"); //obecni gracze
  9. $ar2[] = array("id"=>3, "nick"=>"doszedl","log"=>"doszedl");
  10. $ar2[] = array("id"=>5, "nick"=>"doszedl2","log"=>"doszedl2");
  11. $ar2[] = array("id"=>6, "nick"=>"zostal2","log"=>"zostal2"); //obecni gracze
  12. $ar2[] = array("id"=>9, "nick"=>"doszedl3","log"=>"doszed3");
  13.  
  14. //po pierwsze, zmień struktury danych, których używasz, co ogromnie ułatwi sprawę
  15. //algorytmy wymagają odpowiednich struktur danych, na których operują
  16. //również funkcje przyjmujące parametry działają poprawnie tylko,
  17. //jeśli owe parametry są w formacie wymaganym przez te funkcje tongue.gif
  18.  
  19. $poprzedni = array();
  20. foreach($ar1 as $val){
  21. $poprzedni[] = $val['id'];
  22. }
  23.  
  24. $obecni = array();
  25. foreach($ar2 as $val){
  26. $obecni[] = $val['id'];
  27. }
  28.  
  29. //po drugie, RTFM i stosuj istniejące funkcje zgodnie z ich przeznaczeniem
  30.  
  31. $pozostali = array_intersect($poprzedni, $obecni);
  32. $odeszli = array_diff($poprzedni, $obecni);
  33. $doszli = array_diff($obecni, $poprzedni);
  34.  
  35. //w ten sposób otrzymujesz tablice z odpowiednimi ID rekordów
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.