Упорядочивание данных в массивах PHP: основные методы и их применение

Раздел: Массивы в PHP -> Упорядочивание массивов

В PHP существует множество функций для сортировки массивов. Выбор подходящей функции зависит от типа массива (индексированный или ассоциативный), желаемого порядка (по возрастанию, убыванию, по ключам, по значениям) и необходимости сохранения связей ключ-значение.

Основные функции сортировки массивов

Основное решение: Для сортировки индексированных массивов по значениям в порядке возрастания используется функция sort(). Для ассоциативных массивов, где требуется сохранить ключи, применяется asort().


<?
$numbers = [3, 1, 4, 1, 5, 9];
sort($numbers);
print_r($numbers);
?>

Php массива сортировать (сортировка массива в php)

Array
(
    [0] => 1
    [1] => 1
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 9
)

Пример с ассоциативным массивом:


<?
$assoc = ['b' => 2, 'a' => 3, 'c' => 1];
asort($assoc);
print_r($assoc);
?>
Array
(
    [c] => 1
    [b] => 2
    [a] => 3
)

Возникающие проблемы: Использование sort() на ассоциативном массиве приводит к потере ключей и переиндексации. Решение: применять asort() или ksort() в зависимости от задачи.

Как отсортировать массив по значениям в обратном порядке?

Для сортировки по убыванию используются rsort() (индексированные) и arsort() (ассоциативные).


<?
$arr = [10, 20, 5];
rsort($arr);
print_r($arr);
?>
Array
(
    [0] => 20
    [1] => 10
    [2] => 5
)
Проблема: те же, что и с sort. Для ассоциативных массивов используйте arsort.

Как отсортировать массив по ключам?

Функции ksort() (по возрастанию) и krsort() (по убыванию) сортируют по ключам, сохраняя соответствие.


<?
$fruits = ['orange' => 1, 'apple' => 2, 'banana' => 3];
ksort($fruits);
print_r($fruits);
?>
Array
(
    [apple] => 2
    [banana] => 3
    [orange] => 1
)

Как отсортировать массив с помощью пользовательской функции сравнения?

Для нестандартных критериев применяются usort(), uasort() (сохраняет ключи), uksort() (сортирует по ключам). В callback передаются два элемента, функция должна вернуть -1, 0 или 1.


<?
$words = ['apple', 'banana', 'kiwi', 'strawberry'];
usort($words, function($a, $b) {
    return strlen($a) - strlen($b);
});
print_r($words);
?>
Array
(
    [0] => kiwi
    [1] => apple
    [2] => banana
    [3] => strawberry
)
Типичная ошибка: возвращать логическое значение (true/false) вместо целого числа. Это приводит к неопределенному поведению. Решение: использовать вычитание или $a <=> $b (космический корабль) в PHP 7+.

Как отсортировать многомерный массив по одному из полей?

Используется usort() с доступом к нужному полю внутри callback.


<?
$users = [
    ['name' => 'John', 'age' => 25],
    ['name' => 'Jane', 'age' => 20],
    ['name' => 'Bob', 'age' => 30],
];
usort($users, function($a, $b) {
    return $a['age'] - $b['age'];
});
print_r($users);
?>
Array
(
    [0] => Array ( [name] => Jane [age] => 20 )
    [1] => Array ( [name] => John [age] => 25 )
    [2] => Array ( [name] => Bob [age] => 30 )
)

Как отсортировать несколько массивов одновременно?

Функция array_multisort() позволяет сортировать несколько массивов или многомерный массив, используя один из них как критерий.


<?
$names = ['John', 'Jane', 'Bob'];
$ages  = [25, 20, 30];
array_multisort($ages, SORT_ASC, $names);
print_r($names);
?>
Array
(
    [0] => Jane
    [1] => John
    [2] => Bob
)
Проблема: при сортировке мультимассива теряются ключи, если массивы не являются индексированными. Решение: предварительно переиндексировать.

Как выполнить естественную сортировку строк?

Стандартная сортировка (sort) сравнивает строки лексикографически, что может дать неверный порядок для строк с числами (например, 'img2', 'img10'). Функции natsort() и natcasesort() реализуют алгоритм natural order.


<?
$files = ['img10.jpg', 'img2.jpg', 'img1.jpg'];
sort($files);
print_r($files);
?>
Array
(
    [0] => img1.jpg
    [1] => img10.jpg
    [2] => img2.jpg
)

С использованием natsort:


<?
natsort($files);
print_r($files);
?>
Array
(
    [0] => img1.jpg
    [2] => img2.jpg
    [1] => img10.jpg
)

Дополнительные примеры и расширенные сценарии

Сортировка многомерного массива с сохранением ключей

Используется uasort, которая сохраняет ассоциативные ключи.

Пример

<?
$data = [
    'user1' => ['name' => 'John', 'age' => 25],
    'user2' => ['name' => 'Jane', 'age' => 20],
    'user3' => ['name' => 'Bob', 'age' => 30],
];
uasort($data, function($a, $b) {
    return $a['age'] - $b['age'];
});
print_r($data);
?>
Array
(
    [user2] => Array ( [name] => Jane [age] => 20 )
    [user1] => Array ( [name] => John [age] => 25 )
    [user3] => Array ( [name] => Bob [age] => 30 )
)

Сортировка объектов по свойству

Пример

<?
class Person {
    public $name;
    public $age;
    public function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }
}
$people = [new Person('John', 25), new Person('Jane', 20), new Person('Bob', 30)];
usort($people, function($a, $b) {
    return $a->age - $b->age;
});
foreach ($people as $p) echo $p->name . ' ';
?>
Jane John Bob

Сортировка с учетом локали для русских слов

Пример

<?
setlocale(LC_ALL, 'ru_RU.UTF-8');
$words = ['яблоко', 'апельсин', 'банан', 'вишня'];
usort($words, 'strcoll');
print_r($words);
?>
Array
(
    [0] => апельсин
    [1] => банан
    [2] => вишня
    [3] => яблоко
)
Проблема: функция strcoll может работать некорректно, если локаль не установлена. Решение: проверить setlocale с помощью проверки возвращаемого значения.

Стабильная сортировка (сохранение относительного порядка равных элементов)

В PHP 7 и ранее usort нестабильна. Для стабильности можно добавить индекс сортировки.

Пример

<?
$items = [
    ['name' => 'A', 'group' => 1, 'order' => 0],
    ['name' => 'B', 'group' => 1, 'order' => 1],
    ['name' => 'C', 'group' => 2, 'order' => 0],
    ['name' => 'D', 'group' => 1, 'order' => 2],
];
// Сортируем по group, сохраняя исходный порядок внутри группы
$index = 0;
usort($items, function($a, $b) use (&$index) {
    if ($a['group'] == $b['group']) {
        return $a['order'] - $b['order'];
    }
    return $a['group'] - $b['group'];
});
print_r($items);
?>
Array
(
    [0] => Array ( [name] => A [group] => 1 [order] => 0 )
    [1] => Array ( [name] => B [group] => 1 [order] => 1 )
    [2] => Array ( [name] => D [group] => 1 [order] => 2 )
    [3] => Array ( [name] => C [group] => 2 [order] => 0 )
)

Сортировка с помощью array_multisort по нескольким критериям

Пример

<?
$data = [
    ['name' => 'John', 'age' => 25, 'salary' => 50000],
    ['name' => 'Jane', 'age' => 20, 'salary' => 60000],
    ['name' => 'Bob', 'age' => 30, 'salary' => 40000],
    ['name' => 'Alice', 'age' => 25, 'salary' => 55000],
];
$ages = array_column($data, 'age');
$salaries = array_column($data, 'salary');
$names = array_column($data, 'name');
array_multisort($ages, SORT_ASC, $salaries, SORT_DESC, $data);
print_r($data);
?>
Array
(
    [0] => Array ( [name] => Jane [age] => 20 [salary] => 60000 )
    [1] => Array ( [name] => Alice [age] => 25 [salary] => 55000 )
    [2] => Array ( [name] => John [age] => 25 [salary] => 50000 )
    [3] => Array ( [name] => Bob [age] => 30 [salary] => 40000 )
)

Переиндексация после сортировки

Если после sort() требуется получить новый массив с ключами от 0, но не затрагивать исходный, можно использовать array_values().

Пример

<?
$arr = ['c' => 3, 'a' => 1, 'b' => 2];
$sorted = $arr;
sort($sorted);
$sorted = array_values($sorted);
print_r($sorted);
?>
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)

сортировка массива в PHP - comments

En
Php массива сортировать (php)