Uksort: примеры (PHP)

Функция uksort для сортировки по ключам в PHP
Раздел: Работа с массивами
uksort(array &array, callable callback): bool

Описание функции uksort

Функция uksort в PHP применяется для сортировки массива по ключам с использованием пользовательской функции сравнения. Эта функция полезна, когда стандартные методы сортировки по ключам (ksort, krsort) не подходят из-за сложных или нестандартных форматов ключей.

Аргументы функции

Функция принимает два параметра:

  • array &$array - ссылка на сортируемый массив. Функция изменяет исходный массив.
  • callable $callback - функция сравнения, которая определяет порядок сортировки. Должна принимать два аргумента (значения ключей) и возвращать целое число: меньше нуля, если первый аргумент меньше второго; ноль, если равны; больше нуля, если первый больше второго.

Функция возвращает логическое значение: true при успешной сортировке и false при ошибке.

Примеры использования uksort

Сортировка строковых ключей

Сортировка по длине ключа:

$array = ['яблоко' => 1, 'апельсин' => 2, 'груша' => 3];
uksort($array, function($a, $b) {
    return strlen($a) <=> strlen($b);
});
print_r($array);
Array
(
    [груша] => 3
    [яблоко] => 1
    [апельсин] => 2
)
Сортировка числовых ключей как строк
$array = ['10' => 'десять', '2' => 'два', '1' => 'один'];
uksort($array, 'strnatcmp');
print_r($array);
Array
(
    [1] => один
    [2] => два
    [10] => десять
)

Похожие функции в PHP

ksort и krsort

Стандартные функции для сортировки по ключам в возрастающем и убывающем порядке. Используют естественный порядок сортировки и не требуют функции сравнения.

usort и uasort

Сортируют массив по значениям с пользовательской функцией. usort не сохраняет ключи, uasort сохраняет ассоциацию ключ-значение.

Выбор функции

uksort применяют при нестандартных ключах или сложных правилах сравнения. Для простой сортировки подходят ksort/krsort. Если нужно сортировать по значениям - usort/uasort.

Типичные ошибки

Неправильный возврат значения из callback

Функция сравнения должна возвращать целое число:

$array = ['a' => 1, 'b' => 2];
uksort($array, function($a, $b) {
    return $a <=> $b; // Правильно
    // return ($a < $b) ? -1 : 1; // Неправильно для равных значений
});
Изменение массива внутри callback

Не рекомендуется изменять сортируемый массив внутри функции сравнения:

$array = ['a' => 1, 'b' => 2];
uksort($array, function($a, $b) use (&$array) {
    unset($array['a']); // Непредсказуемое поведение
    return strcmp($a, $b);
});

Изменения в версиях PHP

В PHP 8.0.0 функция теперь выбрасывает TypeError, если параметр callback не является допустимым callback. Ранее возвращала false и вызывала ошибку уровня E_WARNING.

// PHP 7
uksort($array, 'несуществующая_функция'); // Warning
// PHP 8
uksort($array, 'несуществующая_функция'); // TypeError

С PHP 8.0.0 поддерживаются стрелочные функции для более краткой записи:

uksort($array, fn($a, $b) => strlen($a) <=> strlen($b));

Расширенные примеры

Сортировка по нескольким критериям
Пример php
$products = [
    'product_10' => 'Стол',
    'product_2' => 'Стул',
    'item_5' => 'Лампа'
];

uksort($products, function($a, $b) {
    list($aType, $aId) = explode('_', $a);
    list($bType, $bId) = explode('_', $b);
    
    // Сначала по типу, потом по ID
    if ($aType !== $bType) {
        return strcmp($aType, $bType);
    }
    return $aId <=> $bId;
});

print_r($products);
Array
(
    [item_5] => Лампа
    [product_2] => Стул
    [product_10] => Стол
)
Сортировка ключей-дат
Пример php
$events = [
    '2023-12-25' => 'Рождество',
    '2023-01-01' => 'Новый год',
    '2023-06-01' => 'День защиты детей'
];

uksort($events, function($a, $b) {
    return strtotime($a) <=> strtotime($b);
});

print_r($events);
Array
(
    [2023-01-01] => Новый год
    [2023-06-01] => День защиты детей
    [2023-12-25] => Рождество
)

Аналоги в других языках

Uksort в Python

Используют метод sorted() с key или cmp:

dictionary = {'яблоко': 1, 'апельсин': 2, 'груша': 3}
sorted_dict = dict(sorted(dictionary.items(), 
                       key=lambda item: len(item[0])))
print(sorted_dict)
{'груша': 3, 'яблоко': 1, 'апельсин': 2}

Uksort в Javascript

Объекты в JS не гарантируют порядок ключей, но можно использовать Map:

const map = new Map([
  ['яблоко', 1],
  ['апельсин', 2],
  ['груша', 3]
]);
const sorted = new Map([...map].sort(
  (a, b) => a[0].length - b[0].length
));
console.log(Object.fromEntries(sorted));
{ груша: 3, яблоко: 1, апельсин: 2 }

PHP uksort function comments

En
Uksort Sort an array by keys using a user-defined comparison function