PHP 7+
Począwszy od PHP 7, można tego dokonać zwięźle za usort
pomocą anonimowej funkcji, która używa operatora statku kosmicznego do porównywania elementów.
Możesz wykonać sortowanie rosnące w następujący sposób:
usort($inventory, function ($item1, $item2) {
return $item1['price'] <=> $item2['price'];
});
Lub sortowanie malejące takie jak to:
usort($inventory, function ($item1, $item2) {
return $item2['price'] <=> $item1['price'];
});
Aby zrozumieć, jak to działa, należy pamiętać, że usort
bierze podaną przez użytkownika funkcję porównywania, która musi zachowywać się w następujący sposób (z dokumentów):
Funkcja porównania musi zwracać liczbę całkowitą mniejszą, równą lub większą od zera, jeśli pierwszy argument jest uważany za odpowiednio mniejszy, równy lub większy niż drugi.
Pamiętaj też <=>
, że operator statku kosmicznego
zwraca 0, jeśli oba operandy są równe, 1, jeśli lewa jest większa, a -1, jeśli prawa jest większa
dokładnie tego usort
potrzebuje. W rzeczywistości prawie całe uzasadnienie dodania <=>
do języka w https://wiki.php.net/rfc/combined-comparison-operator jest takie, że
sprawia, że pisanie callbacków zamawiania do użytku z usort()
łatwiejsze
PHP 5.3+
PHP 5.3 wprowadził anonimowe funkcje, ale nie ma jeszcze operatora statku kosmicznego. Nadal możemy używać usort
do sortowania naszej tablicy, ale jest to trochę bardziej szczegółowe i trudniejsze do zrozumienia:
usort($inventory, function ($item1, $item2) {
if ($item1['price'] == $item2['price']) return 0;
return $item1['price'] < $item2['price'] ? -1 : 1;
});
Zauważ, że chociaż komparatory zajmujące się wartościami całkowitymi dość często zwracają różnicę wartości $item2['price'] - $item1['price']
, nie możemy tego bezpiecznie zrobić w tym przypadku. Wynika to z faktu, że ceny są liczbami zmiennoprzecinkowymi w przykładzie osoby zadającej pytanie, ale funkcja porównania, do której przekazujemy, usort
musi zwracać liczby całkowite, usort
aby działała poprawnie:
Zwracanie wartości niecałkowitych z funkcji porównania, takich jak liczba zmiennoprzecinkowa, spowoduje wewnętrzne rzutowanie na liczbę całkowitą zwracanej wartości wywołania zwrotnego. Tak więc wartości takie jak 0,99 i 0,1 zostaną rzutowane na liczbę całkowitą 0, która porówna takie wartości jako równe.
Jest to ważna pułapka, o której należy pamiętać podczas korzystania usort
z PHP 5.x! Moja oryginalna wersja tej odpowiedzi popełniła ten błąd, a mimo to zebrałem dziesięć głosów pozytywnych na tysiące wyświetleń, najwyraźniej nikogo nie zauważając poważnego błędu. Łatwość, z jaką takie niedorzeczne osoby jak ja mogą zepsuć funkcje komparatora, jest właśnie przyczyną, dla której łatwiejszy w obsłudze operator statku kosmicznego został dodany do języka w PHP 7.