Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP] Sortowanie, usort, klasy
hunter777
post 19.03.2018, 10:23:30
Post #1





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


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. }
Go to the top of the page
+Quote Post
nospor
post 19.03.2018, 10:31:01
Post #2





Grupa: Moderatorzy
Postów: 36 440
Pomógł: 6290
Dołączył: 27.12.2004




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
Powód edycji: [nospor]:


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
SmokAnalog
post 19.03.2018, 12:37:54
Post #3





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


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.

Ten post edytował SmokAnalog 19.03.2018, 12:44:03
Go to the top of the page
+Quote Post
hunter777
post 19.03.2018, 21:21:09
Post #4





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
SmokAnalog
post 19.03.2018, 22:33:02
Post #5





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


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.

Ten post edytował SmokAnalog 19.03.2018, 22:33:43
Go to the top of the page
+Quote Post
hunter777
post 20.03.2018, 18:41:56
Post #6





Grupa: Zarejestrowani
Postów: 40
Pomógł: 0
Dołączył: 8.02.2017

Ostrzeżenie: (0%)
-----


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...
Go to the top of the page
+Quote Post
SmokAnalog
post 20.03.2018, 23:14:38
Post #7





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Możemy coś zorganizować smile.gif
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 29.03.2024 - 05:57