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