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ć $arraywedług klucza „foo” każdego wpisu, potrzebujesz niestandardowej funkcji porównania . Powyższe sorti 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, 0jeś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 0przypadku, 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');
usortweźmie dwa elementy z tablicy i wywoła cmpz nimi twoją funkcję. Tak cmp()będzie nazywany $ajako array('foo' => 'bar', 'baz' => 42)i $bjak inny array('foo' => ..., 'baz' => ...). Funkcja zwraca następnie, usortktóra z wartości była większa lub czy były równe. usortpowtarza ten proces, przekazując różne wartości dla $ai $bdo momentu posortowania tablicy. cmpFunkcja zostanie wywołana wiele razy, co najmniej tyle razy, ile istnieją wartości w$array , z różnymi kombinacjami wartości dla $ai $bza 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 bazklucza, 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 $ajest mniejsza, równa czy większa niż $b.
Zauważ, że to nie zadziała dobrze dla floatwartości, ponieważ zostaną one zredukowane do inti stracą precyzję. Użyj jawne -1, 0a1 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']);
}
strcmpma dokładnie co się spodziewać cmptutaj, to wraca -1, 0albo 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 foojest 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 $ai $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_multisortaby się tam dostać:
array_multisort($array1, $array2);
Począwszy od PHP 5.5.0, możesz użyć array_columndo 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ź.