Как отсортировать многомерный массив?

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

)
9 ответы
  1. Кодер Матрицы говорит:

    Здорово написано. Огромное спасибо, очень помогло

  2. Михаил говорит:

    Вот то, что я искал. Написано очень понятно и доходчиво. Прям, то что мне нужно было. А то я не мог разобраться, как отсортировать многомерный массив значению ключа.
    Спасибо большое. Профит вам в виде клика. =)

  3. Валера говорит:

    Есть кстати тесты скорости сортировок: https_://intsystem.org/coding/sortirovka-mnogomernyh-massivov-po-klyuchu-na-php/
    И да, все таки array_multisort быстрее всех

  4. Андрей говорит:

    Код с сортировкой по цене — кривой.
    Сравнение идёт по символом и сортировка так же.
    Попробуйте отсортировать последовательность — 1209, 1192, 648
    В итоге получаем 1192, 1209 и за ним 648. Сравнение идёт по первым символом, а не по общему значению.

    • softmaker говорит:

      Спасибо, за замечание! А что можете предложить вы или как улучшить скрипт сортировки?

  5. АК-47 говорит:

    Можно просто вместо strcmt() применить свою функцию для чисел
    function sort_ch($a,$b){
    if($a == $b) return 0;
    return ($a < $b) ? -1 : 1;
    }

  6. plastall.kh.ua говорит:

    В уроке 10  мы научились создавать одномерные массивы. Подобным образом в Java можно создать двумерный, трехмерный, четырехмерный  иначе говоря,  многомерные массивы. Многомерный массив в Java по сути является массивом из массивов.

Комментарии закрыты.