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