Home > OS >  Sort multidimensional array by dynamic key
Sort multidimensional array by dynamic key

Time:11-12

I want to write a PHP function to sort the below given multidimensional array by specific key like (account_id, first_name) and I wrote the below code it works fine for the first level but when I send account_id as parameter, I didn't the expected result.

$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:

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 />";
}

Error:

Warning: Illegal string offset 'account_id' in

Desired result:

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

CodePudding user response:

So long as your sought key name associates to non-array data AND the sought key does not occur multiple times within a respective subset AND every subset is guaranteed to contain the sought key, then you can just use array_walk_recursive() to collect a flat array of values then sort the original array by reference using that flat array of sorting values.

Code: (Demo)

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