Основные одномерные массивы
$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 oF 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 вы также можете извлекать свойства из массива объектов.
Если у вас есть более распространенные случаи, не стесняйтесь редактировать этот ответ.