Test HTTP Requests Tools Blog PHP Quiz API Log In With Github
Test HTTP Requests Tools Blog PHP Quiz API Log In With Github
« Return to the tutorials list
We have updated the website and our policies to make sure your privacy rights and security are respected.
Click here to learn more about the way our website handles your data.

Remove this message.

You can read this article in: English :: Español :: русский

3 Способа Сортировки Многомерных Массивов По Ключам Или Значениям Дочерних Элементов На PHP

Daniel Gheorghe Difficulty: 50 / 50 Tweet
sorted lego pieces

Сортировка многомерных массивов по одному из ключей в дочерний массив часто ставит неопытных программистов в тупик. В сегодняшнем уроке я покажу вам как сделать это 3 способами - вы сами сможете определить, какой проще для вас и обеспечивает наилучшую производительность.

Предположим, что у нас есть огромный массив, вроде того, что приведен ниже, и мы должны отсортировать его по значению последнего дочернего массива - в нашем случае по ключу 'weight' (вес).

  
  <?php
  $array = [
              [
                ['name'=>'John B'],
                ['age'=>30],
                ['sizes'=>
                          [
                          'weight'=>80, 
                          'height'=>120
                          ]
                ]
              ],
              [
                ['name'=>'Marie B'],
                ['age'=>31],
                ['sizes'=>
                          [
                          'weight'=>60, 
                          'height'=>110
                          ]
                ]
              ],
              [
                ['name'=>'Carl M'],
                ['age'=>12],
                ['sizes'=>
                          [
                          'weight'=>70, 
                          'height'=>100
                          ]
                ]
              ],
              [
                ['name'=>'Mike N'],
                ['age'=>19],
                ['sizes'=>
                          [
                          'weight'=>70, 
                          'height'=>150
                          ]
                ]
              ],
              [
                ['name'=>'Nancy N'],
                ['age'=>15],
                ['sizes'=>
                          [
                          'weight'=>60, 
                          'height'=>150
                          ]
                ]
              ],
              [
                ['name'=>'Cory X'],
                ['age'=>15],
                ['sizes'=>
                          [
                          'weight'=>44, 
                          'height'=>150
                          ]
                ]
              ]
  ];
  ?>
  

1 метод сортировки - Использование usort и возвращающей функции (рекомендованный)

Это действительно очень простой способ - usort автоматически попарно прогоняет все элементы массива, сравнивает то, что вам надо и, возвращая -1 или 1 соответственно, присваивает нужный индекс элементу в результирующем массиве. В нашем случае, если 'weight' в $a меньше или равен 'weight' в $b, то содержимое $a будет иметь меньший индекс в результирующем массиве. Смотрите код:


  <?php
  //Метод 1: сортировка массива с использованием функции usort и "вами определенной возвращающей функции"
  function method1($a,$b) 
  {
    return ($a[2]["sizes"]["weight"] <= $b[2]["sizes"]["weight"]) ? -1 : 1;
  }
  usort($array, "method1");
  print_r($array);
  ?>

Пузырьковый метод - метод старой школы

Пузырьковый метод преподавали в рамках курса информатики в 90е. Этот медленный метод сортировки прогоняет массив несколько раз.

Пузырьковый метод сравнивает попарно содержимое соседних элементов массива и, при необходимости, меняет их местами. Это действие выполняется снова и снова, пока массив не будет упорядочен. В нашем примере массив прогоняется до тех пор, пока все веса с ключом $j не будут меньше, чем веса с ключом $j+1. Смотрите код:


<?php
//Метод 2: Пузырьковый метод
//поменять местами два элемента
$j=0;
$flag = true; //установить флаг смены
$temp=0;

while ( $flag )
{
  $flag = false;
  for( $j=0;  $j < count($array)-1; $j++)
  {
    if ( $array[$j][2]["sizes"]["weight"] > $array[$j+1][2]["sizes"]["weight"] )
    {
      $temp = $array[$j];
      //swap the two between each other
      $array[$j] = $array[$j+1];
      $array[$j+1]=$temp;
      $flag = true; //show that a swap occurred
    }
  }
}
print_r($array);
?>

Сделай сам

Некоторые программисты предпочитают в таких случаях просто написать свой код, так что в качестве третьего метода я приведу пример пользовательского кода, решающий ту же задачу.

Задача решена достаточно просто:

Сначала создайте временный пустой массив, потом прогоните сортируемый массив и замените существующие ключи сортируемыми значениями. Пожалуйста, обратите внимание, чтобы новые ключи не повторялись, иначе вы можете потерять элементы. В нашем случае я решил использовать старые ключи и добавить их к новым, чтобы результирующий ключ выглядел как: "new_key" . "some_string" . "old_unique_key". Затем я отсортировал временный массив по ключу с использованием встроенной функции ksort() и использовал значения массива для его переиндексации. Смотрите код:

Обратите внимание, что приведенный код в некоторых случаях отработает некорректно. Например, если один из элементов 'weight' больше либо равен 100, то функция ksort может вернуть неправильный результат. В таких случаях вы можете воспользоваться ksort($temp, SORT_NATURAL).


<?php
  //Метод 3: Сделай сам
  $temp = [];
  foreach ($array as $key => $value)
    $temp[$value[2]["sizes"]["weight"] . "oldkey" . $key] = $value; //добавление уникального идентификатора, чтобы равные веса не перезаписывали друг друга
  ksort($temp); // или ksort($temp, SORT_NATURAL); в абзаце выше пояснено почему
  $array = array_values($temp);
  unset($temp);
  print_r($array);
?>

Надеюсь, вам понравился сегодняшний урок. Спасибо за внимание!