Сортировка массива ассоциативных массивов по значению столбца
Представьте, у меня есть следующий массив в PHP:
$inventory = array(
array("type" => "fruit", "price" => 3.50),
array("type" => "milk", "price" => 2.90),
array("type" => "pork", "price" => 5.43),
);
Я хочу отсортировать элементы массива $inventory
по цене в порядке убывания, чтобы получить следующий результат:
$inventory = array(
array("type" => "pork", "price" => 5.43),
array("type" => "fruit", "price" => 3.50),
array("type" => "milk", "price" => 2.90),
);
Не могли бы вы подсказать, как это сделать?
5 ответ(ов)
Поскольку элементы вашего массива сами являются массивами с строковыми ключами, лучшим решением будет определить собственную функцию сравнения. Это довольно быстро и просто. Попробуйте следующий код:
function invenDescSort($item1, $item2)
{
if ($item1['price'] == $item2['price']) return 0;
return ($item1['price'] < $item2['price']) ? 1 : -1;
}
usort($inventory, 'invenDescSort');
print_r($inventory);
В результате получится следующий массив:
Array
(
[0] => Array
(
[type] => pork
[price] => 5.43
)
[1] => Array
(
[type] => fruit
[price] => 3.5
)
[2] => Array
(
[type] => milk
[price] => 2.9
)
)
Таким образом, массив будет отсортирован по убыванию цены.
Ваш код выглядит вполне корректно для сортировки массива массивов по указанному полю. Давайте сравним его с рекомендациями и обобщим, чтобы выяснить, как его можно улучшить.
Вот функция, которую вы представили:
function sort_array_of_array(&$array, $subfield)
{
$sortarray = array();
foreach ($array as $key => $row)
{
$sortarray[$key] = $row[$subfield];
}
array_multisort($sortarray, SORT_ASC, $array);
}
Функция принимает два параметра: ссылку на массив и имя подполе. Она создает новый массив значений, которые будут использоваться для сортировки, а затем вызывает array_multisort()
для сортировки основного массива.
Вот как вы можете использовать эту функцию:
sort_array_of_array($inventory, 'price');
Обсуждение и улучшения
Проверка наличия поля: Рекомендуется добавить проверку, существует ли указанный ключ в каждом массиве, чтобы избежать ошибок при попытке доступа к неопределенному индексу.
Поддержка сортировки по убыванию: Вы можете добавить дополнительный параметр для указания порядка сортировки (по возрастанию или убыванию).
Вот улучшенная версия функции с учетом предложенных изменений:
function sort_array_of_array(&$array, $subfield, $order = SORT_ASC)
{
$sortarray = array();
foreach ($array as $key => $row)
{
if (isset($row[$subfield])) {
$sortarray[$key] = $row[$subfield];
} else {
// Если поле отсутствует, можно, например, присвоить значение null
$sortarray[$key] = null;
}
}
array_multisort($sortarray, $order, $array);
}
Теперь вы можете вызывать функцию с дополнительным параметром для порядка сортировки:
sort_array_of_array($inventory, 'price', SORT_DESC);
Таким образом, вы получите более безопасную и универсальную функцию для сортировки массива массивов.
Ваша программа на PHP отсортировывает массив товаров по цене, но отображает элемент с самой высокой ценой в качестве первого. Давайте разберем ваш код и его вывод.
Вы определяете массив $inventory
, который содержит элементы с типом и ценой. Затем вы создаете функцию pricesort
, которая сравнивает цены двух элементов. Эта функция возвращает:
0
, если цены равны,-1
, если цена первого элемента больше (что ставит его выше в сортировке),1
, если цена первого элемента меньше (что ставит его ниже в сортировке).
Вы используете функцию usort
для сортировки массива $inventory
по ценам в порядке убывания. Поэтому элемент с самой высокой ценой оказывается первым в отсортированном массиве.
При выводе print("first: ".$inventory[0]['type']."\n\n");
вы получаете тип товара с самой высокой ценой, который в данном случае — это "pork" (снова на высоте в 5.43).
Если бы вы использовали uksort
, это не повлияло бы на результат печати первого элемента, потому что uksort
сортирует массив по ключам, которые здесь не меняются. Ваша программа выводит следующий результат:
first: pork
pork: 5.43
fruit: 3.5
milk: 2.9
Таким образом, вывод показывает наименование самого дорогого товара и его цену, затем следует вывод всех товаров вместе с их ценами, отсортированными по убыванию.
Вы можете отсортировать ассоциативный массив по заданному ключу и направлению с помощью следующей функции на PHP:
/**
* Сортирует ассоциативный массив по конкретному ключу и направлению.
*
* @param array $array Ассоциативный массив для сортировки.
* @param string $key Ключ, по которому производится сортировка.
* @param string $direction Направление сортировки ("ASC" для возрастания, "DESC" для убывания).
* @return array Отсортированный ассоциативный массив.
*/
function sortAssociativeArrayByKey($array, $key, $direction) {
usort($array, function ($a, $b) use ($key, $direction) {
$comparison = $a[$key] <=> $b[$key];
return ($direction === 'DESC') ? -$comparison : $comparison;
});
return $array;
}
Как это работает:
- usort: Эта функция используется для сортировки массива с использованием пользовательской функции сравнения.
- Функция сравнения: Внутренняя функция принимает два элемента массива, сравнивает их по заданному ключу и возвращает результат сравнения. Оператор
<=>
используется для упрощения сравнения. - Направление сортировки: Если указано направление "DESC", сравнение инвертируется для сортировки по убыванию.
Пример использования:
Вы можете вызвать функцию следующим образом:
$array = [
['name' => 'John', 'age' => 25],
['name' => 'Jane', 'age' => 30],
['name' => 'Doe', 'age' => 20]
];
// Сортировка по возрасту по возрастанию
$sortedArray = sortAssociativeArrayByKey($array, 'age', 'ASC');
После вызова $sortedArray
будет содержать элементы, отсортированные по возрасту в порядке возрастания.
Это было протестировано на 100,000 записей:
Время в секундах (рассчитано с помощью функции microtime).
Только для уникальных значений по позициям сортировки.
Решение функции от @Josh Davis:
Затраченное время: 1.58
Мое решение:
Затраченное время: 0.094
Решение:
function SortByKeyValue($data, $sortKey, $sort_flags=SORT_ASC)
{
if (empty($data) or empty($sortKey))
return $data;
$ordered = array();
foreach ($data as $key => $value)
$ordered[$value[$sortKey]] = $value;
ksort($ordered, $sort_flags);
return array_values($ordered); // array_values() добавлен для идентичного результата с multisort
}
Это решение демонстрирует гораздо более быструю работу по сравнению с оригиналом, используя ассоциативный массив для упрощения сортировки. Попробуйте применить это в своем проекте для улучшения производительности.
Сортировка двумерного массива по значению в столбце
Сортировка массива объектов по одному свойству
Сортировка массива объектов по значениям свойств
Можно ли привязать массив к условию IN() в запросе PDO?
Как добавить элементы в пустой массив в PHP?