Podstawowe tablice jednowymiarowe
$array = array(3, 5, 2, 8);
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
$array = array(
array('foo' => 'bar', 'baz' => 42),
array('foo' => ..., 'baz' => ...),
...
);
Jeśli chcesz sortować $array
według klucza „foo” każdego wpisu, potrzebujesz niestandardowej funkcji porównania . Powyższe sort
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ż w 0
przypadku, gdy pierwsza wartość jest wyższa. To wszystko, czego potrzeba:
function cmp(array $a, array $b) {
if ($a['foo'] < $b['foo']) {
return -1;
} else if ($a['foo'] > $b['foo']) {
return 1;
} else {
return 0;
}
}
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:
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($array, 'cmp');
usort
weźmie dwa elementy z tablicy i wywoła cmp
z nimi twoją funkcję. Tak cmp()
będzie nazywany $a
jako array('foo' => 'bar', 'baz' => 42)
i $b
jak inny array('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:
function cmp($a, $b) {
echo 'cmp called with $a:', PHP_EOL;
var_dump($a);
echo 'and $b:', PHP_EOL;
var_dump($b);
}
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 prostu sort($array);
działa.
Niestandardowe porównania numeryczne
Jeśli chcesz sortować według baz
klucza, który jest numeryczny, wszystko, co musisz zrobić, to:
function cmp(array $a, array $b) {
return $a['baz'] - $b['baz'];
}
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 do int
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:
function cmp($a, $b) {
return $a->baz - $b->baz;
}
Funkcje
W funkcji porównawczej możesz zrobić wszystko, czego potrzebujesz, w tym funkcje wywoływania:
function cmp(array $a, array $b) {
return someFunction($a['baz']) - someFunction($b['baz']);
}
Smyczki
Skrót do pierwszej wersji porównania ciągów znaków:
function cmp(array $a, array $b) {
return strcmp($a['foo'], $b['foo']);
}
strcmp
ma dokładnie co się spodziewać cmp
tutaj, to wraca -1
, 0
albo 1
.
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:
function cmp(array $a, array $b) {
return $a['foo'] <=> $b['foo'];
}
Sortowanie według wielu pól
Jeśli chcesz sortować głównie według foo
, ale jeśli foo
jest równy dla dwóch elementów, sortuj według baz
:
function cmp(array $a, array $b) {
if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0) {
return $cmp;
} else {
return $a['baz'] - $b['baz'];
}
}
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” :
function cmp(array $a, array $b) {
static $order = array('foo', 'bar', 'baz');
return array_search($a['foo'], $order) - array_search($b['foo'], $order);
}
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ć:
usort($array, function (array $a, array $b) { return $a['baz'] - $b['baz']; });
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:
return $a['baz'] - $b['baz']; // ascending
return $b['baz'] - $a['baz']; // descending
Sortowanie jednej tablicy na podstawie innej
A potem jest osobliwy array_multisort
, który pozwala sortować jedną tablicę na podstawie innej:
$array1 = array( 4, 6, 1);
$array2 = array('a', 'b', 'c');
Oczekiwany wynik to:
$array2 = array('c', 'a', 'b'); // the sorted order of $array1
Użyj, array_multisort
aby się tam dostać:
array_multisort($array1, $array2);
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:
array_multisort(array_column($array, 'foo'), SORT_DESC, $array);
Począwszy od wersji 7.0.0 PHP można także wyodrębniać właściwości z tablicy obiektów.
Jeśli masz więcej typowych przypadków, edytuj tę odpowiedź.