Biorąc pod uwagę tę tablicę:
$inventory = array(
array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
array("type"=>"pork", "price"=>5.43),
);
Chciałbym posortować $inventory
elementy według ceny, aby uzyskać:
$inventory = array(
array("type"=>"pork", "price"=>5.43),
array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
);
W jaki sposób mogę to zrobić?
Odpowiedzi:
Masz rację, funkcja, której szukasz
array_multisort()
.Oto przykład zaczerpnięty bezpośrednio z instrukcji i dostosowany do twojego przypadku:
źródło
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:
Lub sortowanie malejące takie jak to:
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):Pamiętaj też
<=>
, że operator statku kosmicznegodokł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, żePHP 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: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: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.źródło
uasort
. Jednak po przejrzeniu dokumentów ta odpowiedź jest nadal poprawna w tym przypadku . W przykładzie OP, tablica do sortowania ma sekwencyjne indeksy numeryczne zamiast indeksów łańcuchowych, więcusort
jest bardziej odpowiednie. Użycieuasort
na tablicy indeksowanej sekwencyjnie spowoduje posortowanie tablicy, która nie jest uporządkowana według indeksów numerycznych, tak że pierwszy element widziany wforeach
pętli nie jest$your_array[0]
, co jest mało prawdopodobne.Podczas gdy inni poprawnie zasugerowali użycie
array_multisort()
, z jakiegoś powodu wydaje się, że żadna odpowiedź nie potwierdza istnieniaarray_column()
, co może znacznie uprościć rozwiązanie. Tak więc moja sugestia brzmiałaby:źródło
Ponieważ elementy tablicy same w sobie są tablicami z kluczami łańcuchowymi, najlepszym rozwiązaniem jest zdefiniowanie niestandardowej funkcji porównania. Jest to dość szybkie i łatwe do zrobienia. Spróbuj tego:
Wytwarza następujące:
źródło
uasort( $inventory, function ($a, $b) { if ( $a==$b ) return 0; else return ($a > $b) ? -1 : 1; });
usort
wydaje się bardziej odpowiednie niżuasort
do sortowania tablicy z sekwencyjnymi klawiszami numerycznymi. Skończyło się na tablicy, w której pierwszy element znajduje się w indeksie,1
a drugi w indeksie0
to dziwne zachowanie i pewna pułapka dla osób, które nie są zaznajomione ze szczegółami tablic PHP;usort
daje wynik, którego intuicyjnie oczekujesz.Skończyłem na tym:
Wystarczy wywołać funkcję, przekazując tablicę i nazwę pola tablicy drugiego poziomu. Lubić:
źródło
Możesz używać
usort
z funkcją anonimową, npźródło
strnatcmp
, przeznaczone do porównywania ciągów, wydaje się tutaj dobrze działać. Najwyraźniej realizowany przez niego „naturalny porządek” obejmuje sortowanie ciągów liczbowych numerycznie, a nie leksykalnie.wyjścia:
źródło
Od Sortuj tablicę tablic asocjacyjnych według wartości danego klucza w php :
uasort ( http://php.net/uasort ) pozwala sortować tablicę według własnej zdefiniowanej funkcji. W twoim przypadku to proste:
źródło
cmp
funkcja tu jest nie tak. Ma 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 od drugiego”, ale zamiast tego zwracatrue
lubfalse
. Co ciekawe, wydaje się, że mimo to działa - być może dlatego, że obecna implementacjausort
i znajomi traktują przypadki „mniej niż” i „równa się” identycznie - ale nie licz na to, że będzie działać w przyszłych wersjach PHP. Jeśli spróbują uczynić sortowania stabilnymi (tj. Nie będą niepotrzebnie poruszać się po równych elementach), to się zepsuje.usort
byłaby bardziej odpowiednia niż wuasort
tym wypadku, ponieważuasort
zachowuje związek pomiędzy przyciskami i wartości, które są kłopotliwe i nieoczekiwane, gdy deaing z sekwencyjnym tablicy numerycznej. Na przykład powyższe indeksy$array
po wywołaniuuasort
wynoszą 2, 0 i 1, w tej kolejności. Chyba że z jakiegoś powodu tego chcesz, prawdopodobnie będziesz wygodniejszy w użyciuusort
, co ponownie zindeksuje tablicę, a także zmieni ją.Przetestowano na 100 000 rekordach: Czas w sekundach (obliczony przez funciton microtime). Tylko dla unikalnych wartości przy sortowaniu kluczowych pozycji.
Rozwiązanie funkcji @Josh Davis: Czas spędzony: 1.5768740177155
Moje rozwiązanie: spędzony czas : 0,094044923782349
Rozwiązanie:
źródło
Używam
uasort
takiegoźródło
Ta funkcja jest wielokrotnego użytku:
Domyślnie działa dobrze na wartościach ciągów, ale jeśli wszystkie wartości są liczbami, konieczne będzie wywołanie zwrotne funkcji porównywania liczb.
źródło
usortarr
ale potem dzwoniszuasort
zamiastusort
; może trochę mylące. To ostatnie - w przypadku tablicy sekwencyjnej z indeksami numerycznymi, jak ta przedstawiona w pytaniu - prawdopodobnie tego, czego naprawdę chcesz.Możesz spróbować zdefiniować własną funkcję porównania, a następnie użyć usort .
źródło
Oto metoda, którą znalazłem dawno temu i trochę posprzątałem. Działa to świetnie i można je szybko zmienić, aby akceptować również obiekty.
aby zmienić metodę sortowania obiektów, wystarczy zmienić następujący wiersz:
$tempArray[] = strtolower( $value[ $sortByKey ] );
do$tempArray[] = strtolower( $value->$sortByKey );
Aby uruchomić metodę, po prostu zrób
sortArray($inventory,'price','ASC');
źródło
array_multisort
) lub moja (zusort
) i wydaje się, że nie daje w zamian żadnych korzyści.źródło
Spróbuj tego:
źródło
Kompletna funkcja dynamiczna Przeskoczyłem tutaj, aby sortować tablice asocjacyjne i znalazłem tę niesamowitą funkcję na stronie http://php.net/manual/en/function.sort.php . Ta funkcja jest bardzo dynamiczna i sortuje rosnąco i malejąco według określonego klucza.
Prosta funkcja do sortowania tablicy według określonego klucza. Utrzymuje powiązanie indeksu
źródło
źródło
Spróbuj tego:
w celach informacyjnych patrz: http://php.net/manual/en/function.asort.php
zobacz różne flagi sortowania tutaj: http://www.php.net/manual/en/function.sort.php
źródło