usort()
Узнайте, как функция usort() в PHP сортирует массив на месте с помощью пользовательского коллбэка сравнения, с примерами для строк, чисел и объектов.
Функция usort() в PHP сортирует массив с помощью функции сравнения, которую вы пишете сами. Встроенные функции, такие как sort(), умеют упорядочивать значения лишь одним способом (по возрастанию, по значению), тогда как usort() позволяет задать любое правило — сортировать объекты по свойству, числа в произвольном порядке или строки с учётом дополнительных условий. На этой странице объясняется принцип работы коллбэка сравнения, приводятся примеры для строк, чисел и объектов, а также рассматриваются распространённые подводные камни.
Что такое функция usort()?
Функция usort() — это встроенная функция PHP, сортирующая массив по вашему собственному правилу сравнения. В отличие от стандартных функций сортировки, упорядочивающих по значению или ключу по возрастанию/убыванию, usort() требует коллбэк для определения логики сравнения. Она изменяет исходный массив на месте и возвращает true в случае успеха или false в случае ошибки (то есть массив сортируется, а возвращаемое значение не является отсортированным результатом).
Как работает коллбэк сравнения
Коллбэк получает два элемента, $a и $b, и должен вернуть целое число, указывающее их относительный порядок:
- отрицательное число, если
$aдолжен стоять перед$b, - положительное число, если
$aдолжен стоять после$b, 0, если они считаются равными.
Начиная с PHP 7, оператор космического корабля <=> выполняет именно это за один шаг: $a <=> $b возвращает -1, 0 или 1. Большинство коллбэков сравнения сводятся к единственному return с его использованием.
Примечание: usort() не является стабильной сортировкой. Если два элемента считаются равными, их исходный относительный порядок не гарантируется. Начиная с PHP 8.0 сортировка стабильна, но в более ранних версиях — нет. Кроме того, usort() переиндексирует массив последовательно начиная с 0, поэтому все исходные ключи теряются — используйте uasort(), если нужно сохранить ассоциации ключей.
Синтаксис
Синтаксис функции usort() выглядит следующим образом:
Синтаксис функции usort() в PHP
usort($array, $callback);Здесь $array — это массив, который нужно отсортировать, а $callback — функция обратного вызова, определяющая пользовательские правила сортировки.
Параметры и возвращаемое значение
| Параметр | Тип | Описание |
|---|---|---|
$array | array | Массив для сортировки. |
$callback | callable | Пользовательская функция сравнения. |
Возвращаемое значение: возвращает true в случае успеха или false в случае ошибки.
Пример использования
Рассмотрим пример, демонстрирующий работу функции usort(). Предположим, у нас есть массив имён, которые нужно отсортировать в алфавитном порядке, но по особому правилу: все имена, начинающиеся с «J», должны стоять первыми.
Как использовать функцию usort() в PHP?
В этом примере мы определяем коллбэк, сравнивающий два имени и возвращающий -1, 0 или 1 в соответствии с пользовательскими правилами сортировки. Если первая буква $a равна «J», а первая буква $b — нет, то $a стоит перед $b. Если первая буква $a не «J», а первая буква $b — «J», то $b стоит перед $a. Если оба имени начинаются на «J» или оба не начинаются, то для алфавитного сравнения используется современный оператор PHP космического корабля (<=>).
После выполнения этого кода массив $names будет отсортирован следующим образом:
Array
(
[0] => Jack
[1] => Jenny
[2] => John
[3] => Adam
[4] => Bob
)Сортировка объектов или массивов по полю
Наиболее распространённое практическое применение usort() — упорядочивание списка записей (ассоциативных массивов или объектов) по одному из их полей — то, чего не может сделать sort(). Здесь мы сортируем список продуктов по цене по возрастанию:
<?php
$products = [
["name" => "Book", "price" => 15],
["name" => "Pen", "price" => 2],
["name" => "Laptop", "price" => 900],
];
usort($products, fn ($a, $b) => $a["price"] <=> $b["price"]);
print_r(array_column($products, "name"));Всё сравнение — это единственное выражение с оператором космического корабля. Вывод, начиная с самого дешёвого:
Array
(
[0] => Pen
[1] => Book
[2] => Laptop
)Для сортировки по убыванию достаточно поменять операнды местами: $b["price"] <=> $a["price"].
Распространённые подводные камни
- Неверное использование возвращаемого значения.
usort()возвращаетtrue/false, а не отсортированный массив. Запись$sorted = usort($arr, ...)даст вамtrue, а не данные. Массив сортируется на месте. - Ключи сбрасываются. Исходные ключи отбрасываются и заменяются на
0, 1, 2, …. Используйтеuasort()для сохранения ключей илиuksort()для сортировки по ключам. - Возврат boolean из коллбэка. Возврат
$a > $b(boolean) случайно работает для сортировки по возрастанию, но ломает сортировку по убыванию и равные случаи. Всегда возвращайте целое число — используйте<=>.
Связанные функции
sort()— сортировка массива по значению, по возрастанию, без коллбэка.asort()— сортировка по значению с сохранением ключей.ksort()— сортировка по ключу.uasort()— какusort(), но с сохранением ассоциаций ключей.uksort()— сортировка по ключам с использованием пользовательского коллбэка.
Заключение
В этой статье мы рассмотрели функцию usort() в PHP и показали, как её можно использовать для сортировки массивов с пользовательскими правилами. Определив функцию обратного вызова, вы можете сортировать массивы в любом порядке по собственным правилам. Эта функция особенно полезна в ситуациях, когда встроенных функций сортировки PHP недостаточно для ваших нужд. С помощью usort() вы получаете полный контроль над способом сортировки массивов.