Сортировка многомерного массива по динамическому ключу

Я хочу написать функцию PHP для сортировки приведенного ниже многомерного массива по определенному ключу, например (account_id, first_name), и я написал приведенный ниже код, он отлично работает для первого уровня, но когда я отправляю account_id в качестве параметра, я не ожидал результат.

$data = [
    [
                
        'first_name' => 'GM',
        'middle_name' => null,
        'last_name' => 'Akbari',
        'guest_booking' =>[
            [
                'booking_number' => 20008683,
                'ship_code' => 'OST',
                'room_no' => 'A0073',
                'start_time' => 1438214400,
                'end_time' => 1483142400,
                'is_checked_in' => true,
            ]
        ],
        'guest_account' => [
            [
                'account_id' => 20009503,
                'status_id' => 2,
                'account_limit' => 0,
                'allow_charges' => true,
            ]
        ]
    ],
    [
        'first_name' => 'Alex ',
        'middle_name' => null,
        'last_name' => 'Marvi',
        'guest_booking' => [
            [
                'booking_number' => 10000013,
                'room_no' => 'B0092',
                'is_checked_in' => true,
            ],
        ],
        'guest_account' => [
            [
                'account_id' => 10000500,
                'account_limit' => 300,
                'allow_charges' => true,
            ],
        ],
    ],
];

Функция:

function sortMyArray($array, $target_key = "") {

    $key_values = [];

    foreach ($array AS $key => $value) {
        if (is_array($value)) {
            sortMyArray($value, $target_key);
        }
        $key_values[] = $value[$target_key];
    }
    
    asort($key_values);

    $array_sorted = [];
    foreach ($key_values AS $k => $v) {
        $array_sorted[] = $array[$k];
    }

    echo "<pre>";print_r($array_sorted); echo "<br />";
}

Ошибка:

Warning: Illegal string offset 'account_id' in

Желаемый результат:

...
   ...
    ... 'account_id' => 10000522,
   ...
    ... 'account_id' => 20009503,
   ...

Первая проблема: параметр $array передается по значению, а не по ссылке. Итак, вы сортируете копию массива, и это не влияет на вызывающую сторону.

Barmar 11.11.2022 02:50

Вторая проблема: у вас нет столбца account_id во многих массивах.

Barmar 11.11.2022 02:51

@Barmar У меня есть столбец account_id под индексом guest_account.

Gulmuhammad Akbari 11.11.2022 02:53

Но у вас его нет в индексе guest_booking.

Barmar 11.11.2022 02:54

Вы также используете $value[$target_key]; вне оператора if. Так что $value может даже не быть массивом.

Barmar 11.11.2022 02:55

@Barmar, как вы видите, он находится за пределами оператора if.

Gulmuhammad Akbari 11.11.2022 03:01

Это то, что я сказал. Вы не можете получить доступ к $value[$target_key], если $value не является массивом.

Barmar 11.11.2022 03:02

Можете ли вы добавить желаемый результат к вопросу?

Barmar 11.11.2022 03:03

Вероятно, вам следует использовать usort(), если вы хотите сортировать по определенному ключу.

Barmar 11.11.2022 03:03

@Barmar Я добавил желаемый результат

Gulmuhammad Akbari 11.11.2022 03:51

Не понятно, что в ...?

Barmar 11.11.2022 16:44

@Barmar это другие элементы массива, которые я включил выше.

Gulmuhammad Akbari 11.11.2022 17:29

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

Barmar 11.11.2022 17:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
13
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пока имя искомого ключа связано с данными, не являющимися массивами, И искомый ключ не встречается несколько раз в соответствующем подмножестве, И каждое подмножество гарантированно содержит искомый ключ, тогда вы можете просто использовать array_walk_recursive() для сбора плоского массива значений. затем отсортируйте исходный массив по ссылке, используя этот плоский массив значений сортировки.

Код: (Демо)

function sortMyArray(array &$array, $target_key) {
    $columnValues = [];
    array_walk_recursive(
        $array,
        function($v, $k, $key) use (&$columnValues) {
            if ($k === $key) {
                $columnValues[] = $v;
            }
        },
        $target_key
    );
    array_multisort($columnValues, $array);
}

sortMyArray($data, 'account_id');
var_export($data);

Другие вопросы по теме