Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Sortowanie, usort, klasy
Forum PHP.pl > Forum > Przedszkole
hunter777
mam problem z funkcją usort, wykonałem proste przykłady gdy tablica była podana w kodzie i funkcja działała ale gdy wykonałem klasę, która tworzy tablicę niestety to nie działa i nie wiem dlaczego, mam informację, że odwołuję się do obiektu, który nie jest tablicą a usort wymaga tablicy ale przecież to jest tablica tylko generowana - pewnie gdzieś tu jest klucz ale nie mogę go znaleźć. Potrzebuję posortować po kolumnie, poniżej kod:

  1. <?php
  2.  
  3.  
  4. class Osoba {
  5.  
  6.  
  7. public $imie;
  8. public $nazwisko;
  9. public $wynagrodzenie;
  10. public $wiek;
  11.  
  12. public function __construct ($imie, $nazwisko, $wynagrodznie, $wiek){
  13. $this->imie = $imie;
  14. $this->nazwisko = $nazwisko;
  15. $this->wynagrodzenie = $wynagrodznie;
  16. $this->wiek = $wiek;
  17.  
  18. }
  19.  
  20. public function wypisz() {
  21. echo $this->imie . ' ' . $this->nazwisko . ' ' . $this->wynagrodzenie . ' ' . $this->wiek .'<br>';
  22. }
  23. }
  24.  
  25.  
  26. $osoby = array();
  27.  
  28. $imiona = array('Andrzej', 'Tomasz', 'Karol', 'Igor', 'Kamil');
  29. $nazwiska = array('Nowak', 'Kowalski', 'Lewandowski', 'Stoch', 'Winiarski');
  30. $wynagrodzenia = array(1500, 1200, 2200, 8000, 5000);
  31. $lata = array(23, 40, 22, 18, 29);
  32.  
  33.  
  34. for($i=0;$i<20;$i++){
  35. $osoby[$i] = new Osoba($imiona[rand(0,4)], $nazwiska[rand(0,4)], $wynagrodzenia[rand(0,4)], $lata[rand(0,4)]);
  36. }
  37.  
  38.  
  39. function build_sorter($key) {
  40. return function ($a, $b) use ($key) {
  41.  
  42. if ($a[$key] == $b[$key]) {
  43. return 0;
  44. }
  45. return ($a[$key] < $b[$key]) ? 1 : -1;
  46.  
  47. };
  48. }
  49. print_r($osoby);
  50.  
  51. usort($osoby, build_sorter('wynagrodzenie'));
  52.  
  53. foreach ($osoby as $osoba) {
  54.  
  55.  
  56. $osoba->wypisz();
  57. }
nospor
Naucz sie podawac dokladnie jak brzmi komunikat i w jakiej dokladnie linii...


f ($a[$key] == $b[$key]) {

$a i $b to obiekty a ty sie do nich odwolujesz jak do tablic. Powinno byc $a->wynagrodzenie, reszta anaalogicznie
SmokAnalog
Jeśli używasz PHP7, to możesz to zrobić bardziej elegancko:

  1. usort($osoby, function (Osoba $osobaA, Osoba $osobaB) {
  2. return $osobaA->wynagrodzenie <=> $osobaB->wynagrodzenie;
  3. });


W starszym PHP wystarczy zamienić <=> na znak minus i też zadziała, bo to liczby.

Poza tym masz literówkę: wynagrodznie

No i ostatnia rzecz, takie składanie kilku tablic w jedną tablicę tablic/obiektów po indeksach jest bardzo mało intuicyjne. Lepiej gdybyś miał osobną tablicę dla każdego użytkownika zamiast tablicy imion, tablicy nazwisk itd.
hunter777
dziękuję bardzo SmokAnalog mam akurat starą wersję 5.3 ale minus działa...

rozumiem, że chciałem wrzucić tablicę a powinienem się odwołać do obiektu więc Osoba $osobaA pobiera obiekt o kolejnym indeksie ze wskazaniem na wynagrodzenie i porównuje do obiektu $osobaB, tylko nie rozumiem dlaczego ten minus działa sad.gif
jeszcze przy sortowaniu

  1. function build_sorter($key) {
  2. return function ($a, $b) use ($key) {
  3.  
  4. if ($a[$key] == $b[$key]) {
  5. return 0;
  6. }
  7. return ($a[$key] < $b[$key]) ? 1 : -1;
  8.  
  9. };


tutaj wszystko jest dla mnie jasne ale przy minusie niestety nie sad.gif ale dziękuję smile.gif

pozdrawiam
SmokAnalog
Funkcje używane jako argument do sortowania nie ograniczają się do -1, 0 i 1. Jakakolwiek ujemna wartość zadziała jak -1, a jakakolwiek dodatnia wartość zadziała jak 1. Zauważ, że przy A - B zachodzi taka sama zależność jak u Ciebie:

A - B = 0, gdy A = B
A - B < 0, gdy A < B
A - B > 0, gdy A > B

Ty sortujesz malejąco, więc masz te znaki odwrotnie.

Operator <=> ma taką zaletę, że zadziała nie tylko na liczbach. Zwraca -1, 0 lub 1 w zależności od tego która strona jest większa.

Kiedyś wymyśliłem metodę na zapamiętanie czy powinno się zwrócić -1 czy 1. Otóż funkcja dla sortowania odpowiada na pytanie: Czy te elementy powinno się zamienić miejscami? Możliwe odpowiedzi to: TAK (1), NIE (-1), NIE WIEM (0). I tak na przykładzie Twojego kodu:

  1. return $osobaA->wynagrodzenie - $osobaB->wynagrodzenie;


Jeżeli osoba A ma większe wynagrodzenie niż osoba B, wtedy funkcja zwraca wartość dodatnią. Oznacza to, że zamieniamy miejscami A i B, mając teraz B i A. I to się zgadza, bo B < A, czyli posortowaliśmy rosnąco.
hunter777
naprawdę super jasno to przekazałeś - dziękuję bardzo smile.gif


p.s.
nie dajesz przypadkiem korepetycji z php jeśli tak to bardzo bym chciał usystematyzować wiedzę i podziałać z przykładami itd...
SmokAnalog
Możemy coś zorganizować 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.