Раннее я уже писала статью о сортировке массивов в php, в том числе ассоциативных.
Сегодня хотелось бы рассмотреть более специфичную задачу, а именно сортировку многомерного ассоциативного массива по тому или иному полю.
Допустим у нас есть многомерный ассоциативный массив, который мы хотим сортировать.
$data = [ ['id' => 7, 'age' => 47], ['id' => 3, 'age' => 32], ['id' => 5, 'age' => 58], ['id' => 1, 'age' => 23] ];
Мы можем хотеть сортировать его либо по полю id, либо по полю age. При этом мы можем хотеть сортировать либо в порядке увеличения, либо в порядке уменьшения значения.
Давайте напишем функцию сортировки.
function my_sort($arr, $field, $order){ usort($arr, custom_sorter($field)); if($order == 'desc'){ return array_reverse($arr); } return $arr; }
Функция my-sort принимает в качестве параметров:
- массив, который будем сортировать;
- поле, по которому хотим сортировать;
- направление сортировки, которое может быть либо “asc”, либо “desc”.
Далее мы видим функцию usort – функция для пользовательской сортировки. Она принимает в качестве параметров: массив, который нужно сортировать и функцию, которая будет сортировать (ее мы напишем чуть позже). В нашу функцию custom_sort мы будем передавать поле, по которому хотим производить сортировку.
По умолчанию сортировка будет производиться в направлении увеличения. Поэтому в следующей строке кода мы проверяем, если направление “desc”, то есть сортировка в обратном порядке, то мы просто перевернем полученный массив (array_reverse).
Обратите внимание, что мы не присваиваем результат работы usort никакой переменной. Дело в том, что эта функция изменяет переданный массив, а возвращает она всегда true. Именно по этому записывать результат ее работы в переменную не нужно. $arr уже и так будет изменен.
Осталось написать функцию custom_sorter, которая и будет сортировать массив.
function custom_sorter($field){ return function($a, $b) use ($field) { if($a[$field] == $b[$field]){ return 0; } return ($a[$field] < $b[$field]) ? -1 : 1; }; }
custom_sorter принимает в качестве параметра поле сортировки. Она возвращает анонимную функцию, которая сравнивает элементы по переданному полю и сортирует их.
Весь итоговый код примера получается вот таким:
$data = [ ['id' => 7, 'age' => 47], ['id' => 3, 'age' => 32], ['id' => 5, 'age' => 58], ['id' => 1, 'age' => 23] ]; function my_sort($arr, $field, $order){ usort($arr, custom_sorter($field)); if($order == 'desc'){ return array_reverse($arr); } return $arr; } function custom_sorter($field){ return function($a, $b) use ($field) { if($a[$field] == $b[$field]){ return 0; } return ($a[$field] < $b[$field]) ? -1 : 1; }; }
Чтобы проверить работу функции мы можем вызвать ее и результат распечатать на экран. Например:
var_dump(my_sort($data, 'age', 'asc')); /* array(4) { [0]=> array(2) { ["id"]=> int(1) ["age"]=> int(23) } [1]=> array(2) { ["id"]=> int(3) ["age"]=> int(32) } [2]=> array(2) { ["id"]=> int(7) ["age"]=> int(47) } [3]=> array(2) { ["id"]=> int(5) ["age"]=> int(58) } } */
или
var_dump(my_sort($data, 'id', 'desc')); /* array(4) { [0]=> array(2) { ["id"]=> int(7) ["age"]=> int(47) } [1]=> array(2) { ["id"]=> int(5) ["age"]=> int(58) } [2]=> array(2) { ["id"]=> int(3) ["age"]=> int(32) } [3]=> array(2) { ["id"]=> int(1) ["age"]=> int(23) } } */
Это базовый пример, того, как можно реализовать сортировку многомерного ассоциативного массива. Можно улучшать его под свои нужды.
Надеюсь эта статья вам пригодилась.