Основні одновимірні масиви
$array = array(3, 5, 2, 8);
Застосовувані функції сортування:
sort
rsort
asort
arsort
natsort
natcasesort
ksort
krsort
Різниця між ними полягає лише в тому, чи зберігаються асоціації ключових значень (" a
" функції), сортується від низьких до високих чи зворотних (" r
"), сортує значення або ключі (" k
") і як порівнює значення (" nat
" проти звичайного). Див. Http://php.net/manual/en/array.sorting.php для огляду та посилань на додаткові деталі.
Багатовимірні масиви, включаючи масиви об'єктів
$array = array(
array('foo' => 'bar', 'baz' => 42),
array('foo' => ..., 'baz' => ...),
...
);
Якщо ви хочете сортувати $array
за клавішею "foo" кожного запису, вам потрібна спеціальна функція порівняння . Вищезазначені sort
та пов'язані з ними функції працюють на простих значеннях, які вони вміють порівнювати та сортувати. PHP не просто "знає", що робити зі складним значенням, як-от array('foo' => 'bar', 'baz' => 42)
хоч; тому вам потрібно це сказати.
Для цього вам потрібно створити функцію порівняння . Ця функція 0
містить два елементи і повинна повернутися, якщо ці елементи вважаються рівними, значенням меншим, ніж 0
якщо перше значення є нижчим, а значення вище, ніж 0
якщо перше значення вище. Це все, що потрібно:
function cmp(array $a, array $b) {
if ($a['foo'] < $b['foo']) {
return -1;
} else if ($a['foo'] > $b['foo']) {
return 1;
} else {
return 0;
}
}
Часто вам потрібно буде використовувати анонімну функцію як зворотний дзвінок. Якщо ви хочете використовувати метод або статичний метод, перегляньте інші способи визначення зворотного дзвінка в PHP .
Потім ви використовуєте одну з цих функцій:
Знову ж таки, вони відрізняються лише тим, чи зберігають асоціації ключових значень і сортують за значеннями чи ключами. Прочитайте їх документацію для детальної інформації.
Приклад використання:
usort($array, 'cmp');
usort
візьме два елементи з масиву і викличе вашу cmp
функцію з ними. Так cmp()
буде називатися $a
як array('foo' => 'bar', 'baz' => 42)
і $b
як інше array('foo' => ..., 'baz' => ...)
. Потім функція повертається до того, usort
яке зі значень було більшим, або вони були рівними. usort
повторює цей процес, передаючи різні значення для $a
та $b
до тих пір, поки масив не буде відсортований. cmp
Функція буде викликатися багато разів, по крайней мере , стільки раз , скільки є значення в $array
, з різними комбінаціями значень $a
і $b
кожен раз.
Щоб звикнути до цієї ідеї, спробуйте:
function cmp($a, $b) {
echo 'cmp called with $a:', PHP_EOL;
var_dump($a);
echo 'and $b:', PHP_EOL;
var_dump($b);
}
Все, що ви зробили, - це визначити власний спосіб порівняння двох елементів, це все, що вам потрібно. Це працює з усілякими значеннями.
До речі, це працює на будь-якому значенні, значення не повинні бути складними масивами. Якщо у вас є спеціальне порівняння, яке ви хочете зробити, ви можете зробити це і в простому масиві чисел.
sort
сортує за посиланням і не повертає нічого корисного!
Зауважте, що масив сортується на місці , вам не потрібно присвоювати повернене значення нічому. $array = sort($array)
замінить масив на true
, а не на відсортований масив. Просто sort($array);
працює.
Спеціальні числові порівняння
Якщо ви хочете сортувати за baz
ключовим числом, все, що вам потрібно зробити, це:
function cmp(array $a, array $b) {
return $a['baz'] - $b['baz'];
}
Завдяки PoWEr для MATH це повертає значення <0, 0 або> 0 залежно від того, чи $a
є воно нижче, рівне або більше $b
.
Зауважте, що це не буде добре для float
значень, оскільки вони будуть зведені до int
та втратять точність. Використовуйте явне -1
, 0
і 1
повертати значення замість цього.
Об'єкти
Якщо у вас є масив об'єктів, він працює так само:
function cmp($a, $b) {
return $a->baz - $b->baz;
}
Функції
Ви можете робити все, що потрібно, для функції порівняння, включаючи функції виклику:
function cmp(array $a, array $b) {
return someFunction($a['baz']) - someFunction($b['baz']);
}
Струни
Ярлик для першої версії порівняння рядків:
function cmp(array $a, array $b) {
return strcmp($a['foo'], $b['foo']);
}
strcmp
робить саме те, що cmp
тут очікується , повертається -1
, 0
або 1
.
Оператор космічного корабля
PHP 7 представив оператора космічного корабля , який уніфікує та спрощує рівні / менші / більші за порівняння між типами:
function cmp(array $a, array $b) {
return $a['foo'] <=> $b['foo'];
}
Сортування за кількома полями
Якщо ви хочете сортувати в основному за foo
, але якщо foo
два рівні, то сортуйте за baz
:
function cmp(array $a, array $b) {
if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0) {
return $cmp;
} else {
return $a['baz'] - $b['baz'];
}
}
Для знайомих це еквівалентно запиту SQL з ORDER BY foo, baz
.
Також дивіться цю дуже акуратну скорочену версію і як динамічно створювати таку функцію порівняння для довільної кількості клавіш .
Сортування в ручному, статичному порядку
Якщо ви хочете сортувати елементи в "ручному порядку", наприклад "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);
}
Для всього вищесказаного, якщо ви використовуєте PHP 5.3 або вище (і вам справді слід), використовуйте анонімні функції для коротшого коду та уникайте того, щоб нова глобальна функція плавала навколо:
usort($array, function (array $a, array $b) { return $a['baz'] - $b['baz']; });
Ось таким простим може бути сортування складного багатовимірного масиву. Знову ж таки, просто подумайте з точки зору навчання PHP, як сказати, який із двох предметів є "більшим" ; нехай PHP робить власне сортування.
Крім того, для всього перерахованого вище, для переключення між порядком зростання та спадання просто поміняйте аргументи $a
та $b
аргументи навколо. Наприклад:
return $a['baz'] - $b['baz']; // ascending
return $b['baz'] - $a['baz']; // descending
Сортування одного масиву на основі іншого
А тут є особливість array_multisort
, яка дозволяє сортувати один масив на основі іншого:
$array1 = array( 4, 6, 1);
$array2 = array('a', 'b', 'c');
Очікуваний результат тут буде:
$array2 = array('c', 'a', 'b'); // the sorted order of $array1
Використовуйте, array_multisort
щоб дістатися:
array_multisort($array1, $array2);
З PHP 5.5.0 ви можете використовувати array_column
для вилучення стовпця з багатовимірного масиву та сортування масиву на цьому стовпці:
array_multisort(array_column($array, 'foo'), SORT_DESC, $array);
Станом на PHP 7.0.0 ви також можете витягувати властивості з масиву об'єктів.
Якщо у вас є частіші випадки, сміливо редагуйте цю відповідь.