Как отсортировать многомерный массив?
Доброго времени суток, уважаемые читатели нашего блога! На нашем сайте мы уже касались темы массивов и это был пример того, как сделать выбор нескольких случайных значений из массива. Также уже была статья о том, как с помощью PHP вставлять контекстную рекламу в тексты статей, для решения этой задачи тоже были использованы массивы. А сегодня речть пойдет о том, как отсортировать многомерный массив. Итак, приступим.
Возьмем массив «goods» следующего вида:
<?php $goods[65] = array("price" => 200, "manufacture" => "ТОО Целина"); $goods[45] = array("price" => 400, "manufacture" => "ИП Девяткин"); $goods[78] = array("price" => 800, "manufacture" => "АО Аграрник"); $goods[89] = array("price" => 790, "manufacture" => "ЗАО Красный Восток"); ?>
Необходимо отсортировать данный массив по ключу. Для этого воспользуемся функцией «ksort»:
<?php ksort($goods); print_r($goods); ?>
В результате получаем отсортированный массив по ключу:
Array ( [45] => Array ( [price] => 400 [manufacture] => ИП Девяткин ) [65] => Array ( [price] => 200 [manufacture] => ТОО Целина ) [78] => Array ( [price] => 800 [manufacture] => АО Аграрник ) [89] => Array ( [price] => 790 [manufacture] => ЗАО Красный Восток ) )
Как видим, ключи идут в порядке возрастания от 45 до 89. Теперь нужно отсортировать массив по значению ключа «price» для этого воспользуемся функцией «uasort» и напишем для неё пользовательскую функцию «sort_p»:
<?php function sort_p($a, $b) { return strcmp($a["price"], $b["price"]); } uasort($goods, "sort_p"); print_r($goods); ?>
В результате получаем отсортированный массив по ключу «price»:
Array ( [65] => Array ( [price] => 200 [manufacture] => ТОО Целина ) [45] => Array ( [price] => 400 [manufacture] => ИП Девяткин ) [89] => Array ( [price] => 790 [manufacture] => ЗАО Красный Восток ) [78] => Array ( [price] => 800 [manufacture] => АО Аграрник ) )
Как видим, значения ключа «price» идут в порядке возрастания от 200 до 800. Чтобы значения ключа «price» шли в обратном порядке, по убыванию, поменяем местами параметры функции «strcmp» в пользовательской функции «sort_p»:
<?php function sort_p($a, $b) { return strcmp($b["price"], $a["price"]); } uasort($goods, "sort_p"); print_r($goods); ?>
Получим следующий результат:
Array ( [78] => Array ( [price] => 800 [manufacture] => АО Аграрник ) [89] => Array ( [price] => 790 [manufacture] => ЗАО Красный Восток ) [45] => Array ( [price] => 400 [manufacture] => ИП Девяткин ) [65] => Array ( [price] => 200 [manufacture] => ТОО Целина ) )
Как видим, теперь значения ключа «price» идут в порядке убывания от 800 до 200. Теперь нужно отсортировать массив по значению двух ключей «manufacture» и «price» для этого напишем пользовательскую функцию «sort_pm»:
<?php function sort_pm($a, $b) { $r1 = strcmp($a["manufacture"], $b["manufacture"]); return ($r1 == 0) ? strcmp($a["price"], $b["price"]) : $r1; } uasort($goods, "sort_pm"); print_r($goods); ?>
Теперь сортировка происходит по значениям двух ключей в порядке возрастания, приоритетным является ключ «manufacture».
Array ( [78] => Array ( [price] => 800 [manufacture] => АО Аграрник ) [89] => Array ( [price] => 790 [manufacture] => ЗАО Красный Восток ) [45] => Array ( [price] => 400 [manufacture] => ИП Девяткин ) [65] => Array ( [price] => 200 [manufacture] => ТОО Целина ) )
Если для Вас более приоритетным являются значения ключа «price», то поменяйте местами параметры функций «strcmp» и запишите функцию «sort_pm» следующим образом:
<?php function sort_pm($a, $b) { $r1 = strcmp($a["price"], $b["price"]); return ($r1 == 0) ? strcmp($a["manufacture"], $b["manufacture"]) : $r1; } uasort($goods, "sort_pm"); print_r($goods); ?>
То есть были изменены параметры функций «strcmp». Теперь значения ключа «price» будут приоритетнее, значит сортировка в первую очередь будет осуществлятся по ним, затем будут отсортированы значения ключа «manufacture». Поясним на следующем примере:
<?php $goods[65] = array("price" => 200, "manufacture" => "ТОО Целина"); $goods[45] = array("price" => 400, "manufacture" => "ИП Девяткин"); $goods[57] = array("price" => 400, "manufacture" => "АО Праздник"); $goods[78] = array("price" => 800, "manufacture" => "АО Аграрник"); $goods[89] = array("price" => 790, "manufacture" => "ЗАО Красный Восток"); function sort_pm($a, $b) { $r1 = strcmp($a["price"], $b["price"]); return ($r1 == 0) ? strcmp($a["manufacture"], $b["manufacture"]) : $r1; } uasort($goods, "sort_pm"); print_r($goods); ?>
Мы добавили в массив ещё один элемент с ценой — «400» и производителем — «АО Праздник». Теперь после сортировки этот элемент займет более высокое положение по сравнению с «ИП Девяткин»:
Array ( [65] => Array ( [price] => 200 [manufacture] => ТОО Целина ) [57] => Array ( [price] => 400 [manufacture] => АО Праздник ) [45] => Array ( [price] => 400 [manufacture] => ИП Девяткин ) [89] => Array ( [price] => 790 [manufacture] => ЗАО Красный Восток ) [78] => Array ( [price] => 800 [manufacture] => АО Аграрник ) )
Здорово написано. Огромное спасибо, очень помогло
Вот то, что я искал. Написано очень понятно и доходчиво. Прям, то что мне нужно было. А то я не мог разобраться, как отсортировать многомерный массив значению ключа.
Спасибо большое. Профит вам в виде клика. =)
Пожалуйста, уважаемые!
Есть кстати тесты скорости сортировок: https_://intsystem.org/coding/sortirovka-mnogomernyh-massivov-po-klyuchu-na-php/
И да, все таки array_multisort быстрее всех
Код с сортировкой по цене — кривой.
Сравнение идёт по символом и сортировка так же.
Попробуйте отсортировать последовательность — 1209, 1192, 648
В итоге получаем 1192, 1209 и за ним 648. Сравнение идёт по первым символом, а не по общему значению.
Спасибо, за замечание! А что можете предложить вы или как улучшить скрипт сортировки?
Можно просто вместо strcmt() применить свою функцию для чисел
function sort_ch($a,$b){
if($a == $b) return 0;
return ($a < $b) ? -1 : 1;
}
Проверяйте!
В уроке 10 мы научились создавать одномерные массивы. Подобным образом в Java можно создать двумерный, трехмерный, четырехмерный иначе говоря, многомерные массивы. Многомерный массив в Java по сути является массивом из массивов.