Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Sortowanie wielu zmiennych
Forum PHP.pl > Forum > Przedszkole
Tomplus
Witam,

mam problem z przetworzonymi danymi i nie chcą się posortować w tak jak ja żądam.

Korzystam/korzystałem z dwóch rozwiązań które tutaj przedstawię:


Na początek dane wejściowe - nieposortowane:
  1. $dana[22]['punkty']=3
  2. $dana[22]['gole']=3
  3. $dana[22]['bilans']=1
  4.  
  5. $dana[37]['punkty']=0
  6. $dana[37]['gole']=2
  7. $dana[37]['bilans']=-1
  8.  
  9. $dana[3]['punkty']=3
  10. $dana[3]['gole']=2
  11. $dana[3]['bilans']=2
  12.  
  13. $dana[2]['punkty']=0
  14. $dana[2]['gole']=0
  15. $dana[2]['bilans']=-2
  16.  
  17. $dana[15]['punkty']=0
  18. $dana[15]['gole']=1
  19. $dana[15]['bilans']=-1
  20.  
  21. $dana[40]['punkty']=3
  22. $dana[40]['gole']=2
  23. $dana[40]['bilans']=1
  24.  
  25. $dana[19]['punkty']=1
  26. $dana[19]['gole']=1
  27. $dana[19]['bilans']=0
  28.  
  29. $dana[115]['punkty']=1
  30. $dana[115]['gole']=1
  31. $dana[115]['bilans']=0
  32.  
  33. $dana[24]['punkty']=3
  34. $dana[24]['gole']=2
  35. $dana[24]['bilans']=1
  36.  
  37. $dana[4]['punkty']=0
  38. $dana[4]['gole']=1
  39. $dana[4]['bilans']=-1
  40.  
  41. $dana[33]['punkty']=0
  42. $dana[33]['gole']=1
  43. $dana[33]['bilans']=-2
  44.  
  45. $dana[11]['punkty']=3
  46. $dana[11]['gole']=3
  47. $dana[11]['bilans']=2



Korzystając z funkcji array_multisort()

  1. array_multisort($punkty, SORT_DESC, $bil, SORT_DESC, $strz, SORT_DESC);
  2. foreach ($klub as $k => $v) echo "
  3. <br/>\$dana[{$k}]['punkty']={$klub[$k]['punkty']}
  4. <br/>\$dana[{$k}]['gole']={$klub[$k]['strzelone']}
  5. <br/>\$dana[{$k}]['bilans']={$klub[$k]['bilans']}
  6. ";



Otrzymuje dane posortowane, ale wg ID, a na tym mi nie zależy.



Dlatego wykorzystałem funkcję multisort() dodaną do komentarza funkcji sort()
a przeze mnie odrobinę zmodyfikowaną (chodzi o kolejnosć ASC na DESC)

  1. function multisort($array, $sort_by, $key1, $key2=NULL, $key3=NULL, $key4=NULL, $key5=NULL, $key6=NULL)
  2. {
  3. // sort by ?
  4. foreach ($array as $pos => $val)
  5. $tmp_array[$pos] = $val[$sort_by];
  6. arsort($tmp_array);
  7.  
  8. // display however you want
  9. foreach ($tmp_array as $pos => $val)
  10. {
  11. $return_array[$pos][$sort_by] = $array[$pos][$sort_by];
  12. $return_array[$pos][$key1] = $array[$pos][$key1];
  13. if (isset($key2)) $return_array[$pos][$key2] = $array[$pos][$key2];
  14. if (isset($key3)) $return_array[$pos][$key3] = $array[$pos][$key3];
  15. if (isset($key4)) $return_array[$pos][$key4] = $array[$pos][$key4];
  16. if (isset($key5)) $return_array[$pos][$key5] = $array[$pos][$key5];
  17. if (isset($key6)) $return_array[$pos][$key6] = $array[$pos][$key6];
  18. }
  19. return $return_array;
  20. }


Skrypt sortuje bardzo dobrze. Tylko dot. subtablicy 'punkty'
ale pozostałe już nie sortuje.

jak naprawić ten błąd ? jak zmodyfikowac funkcję aby pozostałe klucze też sortowała ?

wyniki tej funkcji:

  1. $dana[22]['punkty']=3 //Drugie miejsce
  2. $dana[22]['gole']=3
  3. $dana[22]['bilans']=1
  4.  
  5. $dana[40]['punkty']=3 //Piąte miejsce
  6. $dana[40]['gole']=2
  7. $dana[40]['bilans']=1
  8.  
  9. $dana[3]['punkty']=3 //Trzecie miejsce - przypadkiem trafiło
  10. $dana[3]['gole']=2
  11. $dana[3]['bilans']=2
  12.  
  13. $dana[24]['punkty']=3 //Czwarte miejsce - przypadkiem trafiło
  14. $dana[24]['gole']=2
  15. $dana[24]['bilans']=1
  16.  
  17. $dana[11]['punkty']=3 //Pierwsze miejsce
  18. $dana[11]['gole']=3
  19. $dana[11]['bilans']=2
  20.  
  21. $dana[115]['punkty']=1
  22. $dana[115]['gole']=1
  23. $dana[115]['bilans']=0
  24.  
  25. $dana[19]['punkty']=1
  26. $dana[19]['gole']=1
  27. $dana[19]['bilans']=0
  28.  
  29. $dana[4]['punkty']=0
  30. $dana[4]['gole']=1
  31. $dana[4]['bilans']=-1
  32.  
  33. $dana[33]['punkty']=0
  34. $dana[33]['gole']=1
  35. $dana[33]['bilans']=-2
  36.  
  37. $dana[2]['punkty']=0
  38. $dana[2]['gole']=0
  39. $dana[2]['bilans']=-2
  40.  
  41. $dana[37]['punkty']=0
  42. $dana[37]['gole']=2
  43. $dana[37]['bilans']=-1
  44.  
  45. $dana[15]['punkty']=0
  46. $dana[15]['gole']=1
  47. $dana[15]['bilans']=-1



Czy ktoś ma pomysł jak to rozwiązać ?

Szukając na forum, google - to tylko na php.net spotkałem rozwiązanie które mnie satysfakcjonowało, a na innych stronach ogranicza się bez ID. Inaczej się dzieje tak jak w przypadku funkcji array_multisort() Sortuje prawidłowo, to co chcę, ale nie przypisuje danych posortowanych do pierwszorzędnej tablicy.
Noidea
Raczej nie posortujesz takiej tablicy przy użyciu array_multisort.

Użyj uasort:
  1. <?php
  2.  
  3. $dana = array();
  4.  
  5. $dana[22]['punkty']=3;
  6. $dana[22]['gole']=3;
  7. $dana[22]['bilans']=1;
  8.  
  9. $dana[37]['punkty']=0;
  10. $dana[37]['gole']=2;
  11. $dana[37]['bilans']=-1;
  12.  
  13. $dana[3]['punkty']=3;
  14. $dana[3]['gole']=2;
  15. $dana[3]['bilans']=2;
  16.  
  17. $dana[2]['punkty']=0;
  18. $dana[2]['gole']=0;
  19. $dana[2]['bilans']=-2;
  20.  
  21. $dana[15]['punkty']=0;
  22. $dana[15]['gole']=1;
  23. $dana[15]['bilans']=-1;
  24.  
  25. $dana[40]['punkty']=3;
  26. $dana[40]['gole']=2;
  27. $dana[40]['bilans']=1;
  28.  
  29. $dana[19]['punkty']=1;
  30. $dana[19]['gole']=1;
  31. $dana[19]['bilans']=0;
  32.  
  33. $dana[115]['punkty']=1;
  34. $dana[115]['gole']=1;
  35. $dana[115]['bilans']=0;
  36.  
  37. $dana[24]['punkty']=3;
  38. $dana[24]['gole']=2;
  39. $dana[24]['bilans']=1;
  40.  
  41. $dana[4]['punkty']=0;
  42. $dana[4]['gole']=1;
  43. $dana[4]['bilans']=-1;
  44.  
  45. $dana[33]['punkty']=0;
  46. $dana[33]['gole']=1;
  47. $dana[33]['bilans']=-2;
  48.  
  49. $dana[11]['punkty']=3;
  50. $dana[11]['gole']=3;
  51. $dana[11]['bilans']=2;
  52.  
  53.  
  54. function compare( $arr1, $arr2 )
  55. {
  56. $pointDiff = $arr1['punkty'] - $arr2['punkty'];
  57. if( $pointDiff != 0 )
  58. {
  59. return $pointDiff * -1; //DESC
  60. }
  61.  
  62. $goalDiff = $arr1['gole'] - $arr2['gole'];
  63. if( $goalDiff != 0 )
  64. {
  65. return $goalDiff * -1; //DESC
  66. }
  67.  
  68. $balanceDiff = $arr1['bilans'] - $arr2['bilans'];
  69. return $balanceDiff * -1; //DESC
  70. }
  71.  
  72. uasort( $dana, "compare" );
  73.  
  74.  
  75. foreach( $dana as $k => $v )
  76. {
  77. echo "<br>
  78. <br>\$dana[$k]['punkty']=$v[punkty]
  79. <br>\$dana[$k]['gole']=$v[gole]
  80. <br>\$dana[$k]['bilans']=$v[bilans]";
  81. }
  82.  
  83. ?>


Funkcja compare() porównuje dwa "zestawy danych" (tablice $arr1, $arr2). Jeśli zwróci liczbę MNIEJSZĄ od zera, to w posortowanej tablicy pierwszy zestaw będzie PRZED drugim, a jeśli WIĘKSZĄ od zera, to pierwszy zestaw będzie ZA drugim. Jeśli zwróci 0, to kolejność jest niezdefiniowana ($arr1 i $arr2 są równe).
Całość posortuje nam tabelę rosnąco, więc musimy mnożyć różnice razy -1 (albo po sortowaniu użyć array_reverse)
Tomplus
Na to wychodzi że ja sobie życie komplikowałem tamtym skryptem, a Ty rozwiązałeś mój problem w prosty sposób.

Sam kiedyś musiałem użyć tą funkcję, ale nie potrafiłem ją przetłumaczyc na swój język. Teraz Ty świetnie wytłumaczyłeś i na przyszłość będę pamiętał jak korzystać z funkcji porównawczej.

Dziękuje smile.gif
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.