uksort()
PHP uksort(): сортировка массива по ключам с помощью пользовательской функции сравнения. Синтаксис, возвращаемое значение, отличия от ksort() и usort().
Введение
uksort() сортирует массив по ключам с использованием функции сравнения, которую вы пишете самостоятельно. В отличие от ksort(), которая сортирует ключи только в естественном порядке по возрастанию, uksort() позволяет задать собственный порядок — алфавитный, обратный, по длине строки, по произвольному приоритету или любому правилу, которое можно выразить в коде. Связь ключей со значениями всегда сохраняется.
На этой странице рассматриваются синтаксис и возвращаемое значение, принцип работы колбэка сравнения, несколько запускаемых примеров (включая оператор spaceship), типичные подводные камни, а также отличия uksort() от связанных функций сортировки.
Синтаксис
uksort(array &$array, callable $callback): true$array— массив для сортировки. Передаётся по ссылке и сортируется на месте, поэтому исходная переменная изменяется напрямую.$callback— функция сравнения, которая принимает два ключа ($aи$b) и возвращает целое число:- отрицательное число, если
$aдолжен стоять перед$b, 0, если они считаются равными,- положительное число, если
$aдолжен стоять после$b.
- отрицательное число, если
Функция возвращает true (в PHP 8+; ранее она возвращала bool). Поскольку сортировка происходит по ссылке, результат читается из исходной переменной массива, а не из возвращаемого значения.
Колбэк сравнивает ключи, а не значения. Именно это отличает
uksort()отusort()(которая сравнивает значения) иuasort()(которая сравнивает значения, но сохраняет ассоциацию ключей).
Базовый пример: сортировка ключей по алфавиту
Допустим, есть массив фруктов с именами в качестве ключей, и мы хотим упорядочить их по ключу в алфавитном порядке:
<?php
$fruits = [
"orange" => 3,
"apple" => 2,
"banana" => 1,
];
function cmp($a, $b)
{
return strcmp($a, $b);
}
uksort($fruits, "cmp");
print_r($fruits);strcmp() уже возвращает отрицательное, нулевое или положительное целое число, поэтому она напрямую подходит в качестве колбэка. Результат отсортирован по ключу:
Array
(
[apple] => 2
[banana] => 1
[orange] => 3
)Использование оператора spaceship
Начиная с PHP 7, оператор spaceship <=> возвращает -1, 0 или 1 для «меньше», «равно» или «больше» — именно то, что ожидает uksort(). Со стрелочной функцией колбэк сводится к одной строке:
<?php
$data = ["delta" => 1, "alpha" => 2, "charlie" => 3, "bravo" => 4];
uksort($data, fn($a, $b) => $a <=> $b);
print_r($data);Это сортирует ключи по возрастанию:
Array
(
[alpha] => 2
[bravo] => 4
[charlie] => 3
[delta] => 1
)Чтобы изменить порядок на обратный, поменяйте операнды местами: fn($a, $b) => $b <=> $a.
Произвольный порядок сортировки
Настоящая мощь uksort() проявляется при сортировке по правилу, которое не предоставляет ни одна встроенная функция — например, по длине ключа, а при равенстве — по алфавиту:
<?php
$config = [
"id" => 1,
"name" => "Ann",
"is_active" => true,
"x" => 0,
];
uksort($config, function ($a, $b) {
return strlen($a) <=> strlen($b) // shortest keys first
?: strcmp($a, $b); // ties broken alphabetically
});
print_r($config);?: работает как короткое замыкание: возвращает результат сравнения длин, если он не равен 0, иначе возвращает результат алфавитного сравнения:
Array
(
[x] => 0
[id] => 1
[name] => Ann
[is_active] => 1
)Типичные подводные камни
- Функция возвращает
true, а не отсортированный массив. Запись$sorted = uksort($arr, ...)даст вамtrue. Используйте$arrпосле вызова. - Исходный массив изменяется. Если нужно сохранить исходный порядок, скопируйте массив заранее (
$copy = $arr;). - Колбэк должен быть согласованным. Возврат случайных значений (например,
rand(-1, 1)) приводит к непредсказуемым результатам. Для перемешивания используйтеshuffle()для значений илиarray_rand()для ключей. - Возвращайте целое число. Возврат
boolработает через приведение типов, но ненадёжен —falseстановится0(равенство), поэтомуreturn $a < $b;— это ошибка. Используйте<=>илиstrcmp().
Сравнение uksort() с похожими функциями
| Функция | Сортирует по | Пользовательский колбэк | Сохраняет ассоциацию ключей |
|---|---|---|---|
uksort() | ключам | да | да |
ksort() | ключам | нет (естественный порядок) | да |
usort() | значениям | да | нет (переиндексация) |
uasort() | значениям | да | да |
asort() | значениям | нет | да |
Вывод: используйте uksort(), когда нужно упорядочить ассоциативный массив по ключам по правилу, которое ksort() выразить не может. Подробнее об этой теме читайте в разделе Сортировка массивов в PHP.
Заключение
uksort() сортирует ассоциативный массив по ключам с помощью управляемого вами колбэка сравнения, изменяя массив на месте и сохраняя связи ключей со значениями. С оператором spaceship колбэк получается лаконичным, а пользовательская логика позволяет реализовать любой порядок, недоступный встроенным функциям.
Диаграмма
graph LR
A[Array] --> B(Function);
B --> C[Comparison result];
C --> D{Is result negative?};
D -->|Yes| E[Swap];
C -->|No| F[Do not swap];
F --> G[Next comparison];
E --> G[Next comparison];