To pytanie jest przeznaczone jako odniesienie do pytań dotyczących sortowania tablic w PHP. Łatwo jest myśleć, że Twój konkretny przypadek jest wyjątkowy i warty nowego pytania, ale w większości są to niewielkie odmiany jednego z rozwiązań na tej stronie.
Jeśli Twoje pytanie zostało zamknięte jako duplikat tego pytania, poproś o ponowne otwarcie pytania tylko wtedy, gdy możesz wyjaśnić, dlaczego różni się on wyraźnie od wszystkich poniższych.
Jak posortować tablicę w PHP?
Jak posortować złożoną tablicę w PHP?
Jak posortować tablicę obiektów w PHP?
Aby uzyskać praktyczną odpowiedź przy użyciu istniejących funkcji PHP, patrz 1., szczegółową odpowiedź akademicką na temat algorytmów sortowania (które funkcje PHP implementują i które mogą być potrzebne w naprawdę, naprawdę skomplikowanych przypadkach), patrz 2.
Odpowiedzi:
Podstawowe tablice jednowymiarowe
Obowiązujące funkcje sortowania:
sort
rsort
asort
arsort
natsort
natcasesort
ksort
krsort
Różnica między nimi polega jedynie na tym, czy zachowane są powiązania klucz-wartość (funkcje „
a
”), czy sortuje od niskiej do wysokiej, czy odwrotnie („r
”), czy sortuje wartości lub klucze („k
”) i jak porównuje wartości („nat
” vs. normalny). Zobacz http://php.net/manual/en/array.sorting.php aby uzyskać przegląd i łącza do dalszych szczegółów.Tablice wielowymiarowe, w tym tablice obiektów
Jeśli chcesz sortować
$array
według klucza „foo” każdego wpisu, potrzebujesz niestandardowej funkcji porównania . Powyższesort
i powiązane funkcje działają na prostych wartościach, które potrafią porównywać i sortować. PHP nie tylko „wie”, co zrobić ze złożoną wartością, taką jakarray('foo' => 'bar', 'baz' => 42)
chociaż; więc musisz to powiedzieć.Aby to zrobić, musisz utworzyć funkcję porównania . Ta funkcja wymaga dwóch elementów i musi zostać zwrócona,
0
jeśli zostaną one uznane za równe, wartość niższa niż0
przypadku, gdy pierwsza wartość jest niższa, a wartość wyższa niż w0
przypadku, gdy pierwsza wartość jest wyższa. To wszystko, czego potrzeba:Często będziesz chciał użyć funkcji anonimowej jako oddzwaniania. Jeśli chcesz użyć metody lub metody statycznej, zapoznaj się z innymi sposobami określania wywołania zwrotnego w PHP .
Następnie użyj jednej z następujących funkcji:
usort
uasort
uksort
Ponownie różnią się tylko tym, czy zachowują powiązania klucz-wartość i sortują według wartości lub kluczy. Przeczytaj ich dokumentację, aby uzyskać szczegółowe informacje.
Przykładowe użycie:
usort
weźmie dwa elementy z tablicy i wywołacmp
z nimi twoją funkcję. Takcmp()
będzie nazywany$a
jakoarray('foo' => 'bar', 'baz' => 42)
i$b
jak innyarray('foo' => ..., 'baz' => ...)
. Funkcja zwraca następnie,usort
która z wartości była większa lub czy były równe.usort
powtarza ten proces, przekazując różne wartości dla$a
i$b
do momentu posortowania tablicy.cmp
Funkcja zostanie wywołana wiele razy, co najmniej tyle razy, ile istnieją wartości w$array
, z różnymi kombinacjami wartości dla$a
i$b
za każdym razem.Aby przyzwyczaić się do tego pomysłu, spróbuj tego:
Wszystko, co zrobiłeś, to zdefiniowanie niestandardowego sposobu porównywania dwóch elementów, to wszystko, czego potrzebujesz. Działa to z wszelkiego rodzaju wartościami.
Nawiasem mówiąc, działa to na dowolną wartość, wartości nie muszą być złożonymi tablicami. Jeśli masz niestandardowe porównanie, które chcesz wykonać, możesz to zrobić również na prostej tablicy liczb.
sort
sortuje według referencji i nie zwraca niczego przydatnego!Zauważ, że tablica sortuje się na miejscu , nie musisz przypisywać wartości zwracanej do niczego.
$array = sort($array)
zastąpi tablicę tablicątrue
, a nie tablicą posortowaną. Po prostusort($array);
działa.Niestandardowe porównania numeryczne
Jeśli chcesz sortować według
baz
klucza, który jest numeryczny, wszystko, co musisz zrobić, to:Dzięki PoWEr oF MATH zwraca wartość <0, 0 lub> 0 w zależności od tego, czy
$a
jest mniejsza, równa czy większa niż$b
.Zauważ, że to nie zadziała dobrze dla
float
wartości, ponieważ zostaną one zredukowane doint
i stracą precyzję. Użyj jawne-1
,0
a1
zwracają wartości zamiast.Obiekty
Jeśli masz tablicę obiektów, działa to w ten sam sposób:
Funkcje
W funkcji porównawczej możesz zrobić wszystko, czego potrzebujesz, w tym funkcje wywoływania:
Smyczki
Skrót do pierwszej wersji porównania ciągów znaków:
strcmp
ma dokładnie co się spodziewaćcmp
tutaj, to wraca-1
,0
albo1
.Operator statku kosmicznego
PHP 7 wprowadził operatora statku kosmicznego , który ujednolica i upraszcza równe / mniejsze / większe niż porównania między typami:
Sortowanie według wielu pól
Jeśli chcesz sortować głównie według
foo
, ale jeślifoo
jest równy dla dwóch elementów, sortuj wedługbaz
:Dla tych, którzy są zaznajomieni, jest to odpowiednik zapytania SQL z
ORDER BY foo, baz
.Zobacz także bardzo zgrabną wersję skróconą i jak dynamicznie utworzyć taką funkcję porównania dla dowolnej liczby kluczy .
Sortowanie w ręcznym, statycznym porządku
Jeśli chcesz posortować elementy w „kolejności ręcznej”, takiej jak „foo”, „bar”, „baz” :
W związku z powyższym, jeśli używasz PHP 5.3 lub nowszego (i naprawdę powinieneś), użyj anonimowych funkcji, aby skrócić kod i uniknąć sytuacji, w której inna globalna funkcja będzie się zmieniać:
Tak proste może być sortowanie złożonej tablicy wielowymiarowej. Ponownie, pomyśl tylko w kategoriach uczenia PHP, jak powiedzieć, który z dwóch elementów jest „większy” ; pozwól PHP dokonać właściwego sortowania.
Również w przypadku wszystkich powyższych elementów, aby przełączać się między kolejnością rosnącą a malejącą, wystarczy zamienić argumenty
$a
i$b
. Na przykład:Sortowanie jednej tablicy na podstawie innej
A potem jest osobliwy
array_multisort
, który pozwala sortować jedną tablicę na podstawie innej:Oczekiwany wynik to:
Użyj,
array_multisort
aby się tam dostać:Począwszy od PHP 5.5.0, możesz użyć
array_column
do wyodrębnienia kolumny z tablicy wielowymiarowej i posortowania tablicy w tej kolumnie:Począwszy od wersji 7.0.0 PHP można także wyodrębniać właściwości z tablicy obiektów.
źródło
array_flip()
szybsze wyszukiwanie pozycji, np.$order[$a['foo']]
Zamiastarray_search($a['foo'], $order)
.Cóż, najbardziej podstawowe metody są już objęte deceze. Chciałbym spojrzeć na inne rodzaje
Sortowanie za pomocą SPL
SplHeap
Wynik
SplMaxHeap
Klasa SplMaxHeap zapewnia główne funkcje sterty, utrzymując maksimum na szczycie.
SplMinHeap
Inne rodzaje sortowania
Sortowanie bąbelkowe
Z artykułu w Wikipedii na temat Sortowania baniek:
Sortuj wybór
Z artykułu w Wikipedii na temat sortowania:
Sortowanie przez wstawianie
Z artykułu w Wikipedii na temat sortowania wstawek:
Shellsort
Z artykułu w Wikipedii na temat Shellsort:
Sortuj według rodzaju grzebienia
Z artykułu w Wikipedii na temat sortowania Comb:
Scal sortowanie
Z artykułu w Wikipedii na temat Sortowania:
Szybkie sortowanie
Z artykułu w Wikipedii na temat Quicksort:
Sortowanie permutacyjne
Z artykułu w Wikipedii na temat sortowania permutacyjnego:
Sortowanie Radix
Z artykułu w Wikipedii na temat sortowania Radix:
źródło
O(n^2)
porównania, jeśli użyjemy tylko pierwszego elementu jako elementu przestawnego)Rodzaj stabilny
Powiedzmy, że masz taką tablicę:
A teraz chcesz posortować tylko według pierwszej litery:
Wynik jest następujący:
Ten rodzaj nie był stabilny!
Uważny obserwator mógł zauważyć, że algorytm sortowania tablic (QuickSort) nie dał stabilnego wyniku i że pierwotna kolejność między słowami tej samej pierwszej litery nie została zachowana. Ten przypadek jest trywialny i powinniśmy porównać cały ciąg, ale załóżmy, że twój przypadek użycia jest bardziej skomplikowany, na przykład dwa kolejne rodzaje na różnych polach, które nie powinny wzajemnie się anulować.
Transformacja Schwartziana
Transformacja Schwartziana , zwana także idiomem dekorowanie-sortowanie-undekorowanie, daje efekt stabilnego sortowania z wewnętrznie niestabilnym algorytmem sortowania.
Najpierw dekorujesz każdy element tablicy inną tablicą składającą się z klucza głównego (wartość) i klucza dodatkowego (jego indeks lub pozycja):
To przekształca tablicę w to:
Teraz dostosowujemy krok porównania; porównujemy ponownie pierwszą literę, ale jeśli są takie same, klucz pomocniczy służy do zachowania pierwotnej kolejności:
Następnie cofamy dekorację:
Wynik końcowy:
Co z ponownym użyciem?
Trzeba było przepisać funkcję porównania, aby pracować z transformowanymi elementami tablicy; możesz nie chcieć edytować swoich delikatnych funkcji porównawczych, więc oto opakowanie funkcji porównawczej:
Napiszmy krok sortowania za pomocą tej funkcji:
Voila! Twój dziewiczy kod porównania powrócił.
źródło
Począwszy od PHP 5.3 z zamknięciami, możliwe jest również użycie zamknięcia, aby określić kolejność twojego rodzaju.
Na przykład założenie, że $ tablica jest tablicą obiektów zawierających właściwość miesiąca.
źródło
LINQ
W .NET często używa się LINQ do sortowania, co zapewnia znacznie lepszą składnię w porównaniu z funkcjami porównywania, szczególnie gdy obiekty muszą być sortowane według wielu pól. Istnieje kilka portów LINQ do PHP, w tym biblioteka YaLinqo *. Dzięki niemu tablice mogą być sortowane za pomocą jednej linii bez pisania skomplikowanych funkcji porównawczych.
Porównania można dodatkowo dostosować, przekazując oddzwonienie jako drugi argument, na przykład:
Tutaj
'$v->count'
jest skrótemfunction ($v) { return $v->count; }
(można użyć obu). Te łańcuchy metod zwracają iteratory, iteratory można przekształcić w tablice, dodając->toArray()
na końcu w razie potrzeby.Wewnętrznie
orderBy
i metody pokrewne wywołać odpowiednie funkcje sortowania tablicy (uasort
,krsort
,multisort
,usort
itd.).LINQ zawiera o wiele więcej metod inspirowanych SQL: filtrowanie, grupowanie, łączenie, agregowanie itp. Najlepiej nadaje się do przypadków, w których złożone transformacje tablic i obiektów muszą być wykonywane bez polegania na bazach danych.
* opracowane przeze mnie, zobacz plik Readme, aby uzyskać więcej informacji i porównanie z innymi portami LINQ
źródło
Sortowanie wielowymiarowe według wartości klucza
Naturalny rodzaj tablicy wielowymiarowej według wartości klucza, a także zachowaj pierwotną kolejność (nie tasuj głównych kluczy):
Przypadek testowy:
źródło
Bardzo wygodne jest sortowanie tablic za pomocą funkcji sortowania z Nspl :
Podstawowe sortowanie
Sortowanie według wyniku funkcji
Sortowanie tablicy wielowymiarowej
Sortowanie tablicy obiektów
Sortowanie za pomocą funkcji porównania
Możesz zobaczyć wszystkie te przykłady tutaj .
źródło
Jeśli chcesz zamówić według wartości klucza, możesz to zrobić w jednej linii, elegancko i wyraźnie. To będzie sortować według ceny rosnąco. Wykorzystuje tablicę_multisort i tablicę_kolumny.
produkować
źródło
Ta strona jest bardzo obszerna, ale chcę dodać trochę więcej o niesamowitej użyteczności operatora statku kosmicznego (trójdrożny operator porównania) - pięknego potomka PHP7 +.
Wykorzystanie operatora statku kosmicznego do wdrożenia wielu warunków sortowania
To czyni wielkie postępy w zmniejszaniu wzdęć i poprawianiu czytelności.
Pisząc niestandardową funkcję sortowania (
usort()
/uasort()
/uksort()
) w celu przetworzenia wielu warunków, wystarczy napisać zbalansowane tablice po obu stronach operatora i zwrócić wynik. Nigdy więcej zagnieżdżonych bloków warunkowych lub wielokrotnych zwrotów.Elementy z obu stron operatora będą przemieszczane od lewej do prawej, po jednym, i zwracają ocenę, gdy tylko pojawi się brak powiązania lub gdy wszystkie elementy zostaną porównane.
Przykładowe dane z moich demonstracji:
Demonstracje (aby uniknąć rozdęcia strony Stackoverflow, proszę zobaczyć link do wersji demonstracyjnych ):
Logika sortowania:
float ASC
Logika sortowania:
boolean ASC
Logika sortowania:
natString ASC
Ta składnia umożliwia eleganckie sortowanie wartości, wyników funkcjonalnych, głęboko zagnieżdżonych danych i kierunku sortowania. Jest to zdecydowanie warte umieszczenia paska narzędzi php ... na wypadek, gdy przetwarzasz dane inne niż baza danych - ponieważ oczywiście SQL byłby znacznie bardziej sensowną techniką.
Według własnego uznania, z PHP7.4 możesz używać składni strzałek z tymi anonimowymi funkcjami. Ten sam skrypt ze składnią strzałki .
źródło
Jeśli ktoś chce prostszego rozwiązania do manipulowania tablicami, wystarczy użyć pakietu Laravel Collection, który ma zaimplementowaną funkcję sortBy, która pozwala na proste sortowanie według kluczy.
tzn. aby posortować najpierw według a, a następnie b, a następnie c, poprawną klauzulą byłoby
https://packagist.org/packages/tightenco/collect
źródło
Istnieje kilka sposobów sortowania tablicy. Wymienię kilka metod wykonywania tego zadania. Po pierwsze podam tablicę liczb całkowitych nazywaną „$ numbers”.
Jest to normalny sposób tworzenia tablicy. Załóżmy, że chcę posortować tę tablicę w kolejności rosnącej. W tym celu można użyć metody „sort ()”.
Teraz rozważ wynik tego,
Widać, że drukowana tablica liczb jest posortowana. Jeśli chcesz, aby ta tablica liczb była sortowana w porządku malejącym, do tego zadania można użyć metody „rsort ()”.
rozważ wynik.
Teraz tablica jest sortowana w kolejności malejącej. Ok, rozważmy tablicę asocjacyjną. Dam tablicę asocjacyjną (tablica asocjacyjna oznacza, że tablica, której każdy indeks ma unikalną wartość klucza).
Teraz chcę posortować tę tablicę w porządku rosnącym według ich wartości. Można do tego użyć metody asort ().
W przypadku sortowania malejącego według ich wartości można zastosować metodę „arsort ()”. Załóżmy, że chcesz posortować tę tablicę według ich wartości klucza. W tym można użyć metody „ksort ()”.
Teraz rozważ wynik.
Teraz tablica jest sortowana według wartości klucza. Jeśli chcesz posortować tablicę w kolejności malejącej według wartości klucza, można użyć metody „krsort ()”.
Teraz tablica asocjacyjna jest sortowana w kolejności malejącej według wartości klucza. Spójrz na wynik.
Oto niektóre metody sortowania tablicy w porządku rosnącym lub malejącym w php. Mam nadzieję, że uda ci się znaleźć pomysł.
źródło
Najprostszym jest użycie funkcji usort do sortowania tablicy bez zapętlania: Poniżej znajduje się przykład:
To posortuje w kolejności odfiltrowywania:
To posortuje w kolejności wysyłania:
źródło