Как отсортировать многомерный массив?
Доброго времени суток, уважаемые читатели нашего блога! На нашем сайте мы уже касались темы массивов и это был пример того, как сделать выбор нескольких случайных значений из массива. Также уже была статья о том, как с помощью 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] => АО Аграрник
)
)
SoftMaker.kz
SoftMaker.kz
SoftMaker.kz
Здорово написано. Огромное спасибо, очень помогло
Вот то, что я искал. Написано очень понятно и доходчиво. Прям, то что мне нужно было. А то я не мог разобраться, как отсортировать многомерный массив значению ключа.
Спасибо большое. Профит вам в виде клика. =)
Пожалуйста, уважаемые!
Есть кстати тесты скорости сортировок: 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 по сути является массивом из массивов.