uasort()
Функция uasort() сортирует ассоциативный массив по значениям с помощью пользовательской функции сравнения, сохраняя ключи.
Сортировка массивов в PHP с помощью uasort()
Функция PHP uasort() сортирует ассоциативный массив по значениям с использованием написанной вами функции сравнения, при этом сохраняя связь каждого значения с исходным ключом. Буква «u» означает user-defined (вы задаёте логику сравнения), а буква «a» — associative (пары ключ/значение сохраняются).
На этой странице рассматривается, что делает uasort(), её синтаксис, как написать корректную функцию сравнения и практические примеры для обычных, ассоциативных и многомерных массивов — каждый результат является реальным выводом запущенного кода.
Что делает uasort() и когда её использовать
Большинство функций сортировки PHP либо игнорируют ключи, либо позволяют сортировать только по встроенным правилам сравнения. uasort() даёт вам сразу оба преимущества:
- Вы управляете порядком. Вы передаёте коллбэк, который определяет, какое из двух значений идёт первым, так что вы можете сортировать по длине, по вложенному полю, в обратном порядке, по пользовательскому списку приоритетов — всё, что можно выразить в коде.
- Ключи остаются со своими значениями. После сортировки
$array["John"]по-прежнему указывает на значение John; меняется только порядок итерации по парам.
Используйте uasort(), когда оба условия истинны: нужно пользовательское правило и ключи несут смысловую нагрузку (имя, ID, slug). Если ключи — просто позиции 0, 1, 2…, usort() проще, так как переиндексирует массив за вас. Если нужно сортировать по ключам, а не по значениям, используйте uksort(). Если достаточно обычной сортировки по значениям по возрастанию/убыванию без пользовательского правила, asort() и arsort() справятся без коллбэка.
Синтаксис
uasort(array &$array, callable $callback): boolarray &$array— сортируемый массив. Символ&означает передачу по ссылке:uasort()сортирует массив на месте и возвращаетtrue/false, но не возвращает новый отсортированный массив.callable $callback— ваша функция сравнения. Она получает два значения,$aи$b, и должна возвращать целое число, указывающее PHP их относительный порядок.- Возвращаемое значение —
bool, всегдаtrue(возвращается значение, чтобы функцию можно было использовать в выражениях, однако обычно её вызывают ради побочного эффекта на$array).
Поскольку массив изменяется на месте, пишите
uasort($array, ...);на отдельной строке — не пишите$array = uasort($array, ...), это перезапишет данные значениемtrue.
Написание функции сравнения
Коллбэк сравнивает два значения и возвращает целое число:
- отрицательное число, если
$aдолжен идти перед$b, 0, если порядок не важен (значения считаются равными),- положительное число, если
$aдолжен идти после$b.
Самый чистый способ получить такой результат — оператор spaceship <=>, который возвращает ровно -1, 0 или 1:
// ascending
fn($a, $b) => $a <=> $b;
// descending — just flip the operands
fn($a, $b) => $b <=> $a;Старый стиль ($a < $b) ? -1 : 1 тоже работает, но никогда не возвращает 0, поэтому равные элементы получают произвольный порядок. Предпочитайте <=>; он короче, корректно обрабатывает случай равенства и работает для чисел, строк и массивов.
Пример 1: Сортировка значений индексированного массива (ключи сохраняются)
Здесь uasort() сортирует числа по возрастанию, но обратите внимание: исходные ключи перемещаются вместе со значениями — это отличие от sort(), который перенумеровал бы их с 0…9.
Вывод:
Array
(
[1] => 1
[3] => 1
[6] => 2
[0] => 3
[9] => 3
[2] => 4
[4] => 5
[8] => 5
[7] => 6
[5] => 9
)Пример 2: Сортировка ассоциативного массива по значению
Это наиболее распространённый сценарий: сортировка людей по возрасту с сохранением их имён в качестве ключей.
Вывод:
Array
(
[Mary] => 28
[Jane] => 28
[John] => 32
[David] => 37
[Bob] => 45
)Чтобы сортировать от старшего к младшему, поменяйте операнды местами: fn($a, $b) => $b <=> $a.
Пример 3: Сортировка многомерного массива по вложенному полю
Когда каждый элемент сам является массивом, коллбэк получает весь подмассив, поэтому вы обращаетесь к нему по индексу, чтобы выбрать поле для сортировки. Здесь мы сортируем по возрасту ([1]).
Вывод:
Array
(
[1] => Array
(
[0] => Mary
[1] => 28
)
[3] => Array
(
[0] => Jane
[1] => 28
)
[0] => Array
(
[0] => John
[1] => 32
)
[4] => Array
(
[0] => David
[1] => 37
)
[2] => Array
(
[0] => Bob
[1] => 45
)
)Для строк с ассоциативным ключом замените $a[1] на что-то вроде $a['age'].
uasort() vs usort()
Функции идентичны, за исключением работы с ключами. Запустим одни и те же данные через обе:
<?php
$ages = ["John" => 32, "Mary" => 28, "Bob" => 45];
$copy = $ages;
usort($copy, fn($a, $b) => $a <=> $b);
echo "usort (keys lost):\n";
print_r($copy);
uasort($ages, fn($a, $b) => $a <=> $b);
echo "uasort (keys kept):\n";
print_r($ages);Вывод:
usort (keys lost):
Array
(
[0] => 28
[1] => 32
[2] => 45
)
uasort (keys kept):
Array
(
[Mary] => 28
[John] => 32
[Bob] => 45
)Распространённые ошибки
- Возвращается
true, а не массив. Читайте отсортированный результат из переменной, которую вы передали, а не из возвращаемого значения. - Сортировка нестабильна до PHP 8.0. Если два значения равны, их относительный порядок в старых версиях был определён реализацией. Начиная с PHP 8.0, все функции сортировки (включая
uasort()) стабильны, поэтому равные элементы сохраняют исходный порядок. - Всегда обрабатывайте случай равенства. Возврат
1для «не меньше» (вместо0) может нарушить порядок равных элементов в старых версиях PHP и попросту некорректен;<=>обрабатывает это автоматически.
Связанные функции
usort()— такая же сортировка с пользовательским правилом, но переиндексирует ключи.uksort()— сортировка по ключам с пользовательским коллбэком.asort()/arsort()— сортировка по значению по возрастанию/убыванию без коллбэка.ksort()— сортировка по ключам без коллбэка.- Сортировка массивов в PHP — обзор всех функций сортировки и когда использовать каждую.
Заключение
uasort() — инструмент для сортировки ассоциативного массива по значениям с собственным правилом сравнения при сохранении ключей. Используйте его вместе с оператором spaceship для лаконичных корректных коллбэков, помните, что сортировка выполняется на месте, и выбирайте его вместо usort() всегда, когда ключи имеют смысловую нагрузку.