6

Сортировка массива ассоциативных массивов по значению столбца

12

Представьте, у меня есть следующий массив в 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 ответ(ов)

0

Поскольку элементы вашего массива сами являются массивами с строковыми ключами, лучшим решением будет определить собственную функцию сравнения. Это довольно быстро и просто. Попробуйте следующий код:

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
        )
)

Таким образом, массив будет отсортирован по убыванию цены.

0

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

Вот функция, которую вы представили:

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');

Обсуждение и улучшения

  1. Проверка наличия поля: Рекомендуется добавить проверку, существует ли указанный ключ в каждом массиве, чтобы избежать ошибок при попытке доступа к неопределенному индексу.

  2. Поддержка сортировки по убыванию: Вы можете добавить дополнительный параметр для указания порядка сортировки (по возрастанию или убыванию).

Вот улучшенная версия функции с учетом предложенных изменений:

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);

Таким образом, вы получите более безопасную и универсальную функцию для сортировки массива массивов.

0

Ваша программа на 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

Таким образом, вывод показывает наименование самого дорогого товара и его цену, затем следует вывод всех товаров вместе с их ценами, отсортированными по убыванию.

0

Вы можете отсортировать ассоциативный массив по заданному ключу и направлению с помощью следующей функции на 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;
}

Как это работает:

  1. usort: Эта функция используется для сортировки массива с использованием пользовательской функции сравнения.
  2. Функция сравнения: Внутренняя функция принимает два элемента массива, сравнивает их по заданному ключу и возвращает результат сравнения. Оператор <=> используется для упрощения сравнения.
  3. Направление сортировки: Если указано направление "DESC", сравнение инвертируется для сортировки по убыванию.

Пример использования:

Вы можете вызвать функцию следующим образом:

$array = [
    ['name' => 'John', 'age' => 25],
    ['name' => 'Jane', 'age' => 30],
    ['name' => 'Doe', 'age' => 20]
];

// Сортировка по возрасту по возрастанию
$sortedArray = sortAssociativeArrayByKey($array, 'age', 'ASC');

После вызова $sortedArray будет содержать элементы, отсортированные по возрасту в порядке возрастания.

0

Это было протестировано на 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
}

Это решение демонстрирует гораздо более быструю работу по сравнению с оригиналом, используя ассоциативный массив для упрощения сортировки. Попробуйте применить это в своем проекте для улучшения производительности.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь