2

I have a complex multidimensional array; the structure is like this:

[
    [
        'countries' => [
            ['country_code' => 'US', 'growth' => 3.57],
            ['country_code' => 'CA', 'growth' => 4.77],
            ['country_code' => 'TT', 'growth' => 0],
        ],
        'group_name' => 'North America',
    ],
    [
        'countries' => [
            ['country_code' => 'BR', 'growth' => 2.19],
            ['country_code' => 'PE', 'growth' => 1.78],
            ['country_code' => 'UY', 'growth' => 8.83],
            ['country_code' => 'MX', 'growth' => 3.83],
        ],
        'group_name' => 'South America',
    ],
]

I want to sort the subarrays inside each countries entry (maybe by using array_multisort) so that they are sorted according to growth (highest first)

So that the sorted array will be:

[
    [
        'countries' => [
            ['country_code' => 'CA', 'growth' => 4.77],
            ['country_code' => 'US', 'growth' => 3.57],
            ['country_code' => 'TT', 'growth' => 0],
        ],
        'group_name' => 'North America',
    ],
    [
        'countries' => [
            ['country_code' => 'UY', 'growth' => 8.83],
            ['country_code' => 'MX', 'growth' => 3.83],
            ['country_code' => 'BR', 'growth' => 2.19],
            ['country_code' => 'PE', 'growth' => 1.78],
        ],
        'group_name' => 'South America',
    ],
]
1
  • I want to sort a complex array and I don't know how to do it. I have read manual but could not get a good example for such a complex array. Commented Jul 17, 2012 at 15:05

3 Answers 3

2

Worst case scenario, you make your own sort function and use usort.
It's actually designed for these sorts of things.

In your case, you'll pass $arr[$i]['countries'] and have the comparison function sort based on $arr['growth'].

0

I've used my following sorting function for years now:

/**
 * sorting array of associative arrays - multiple row sorting using a closure
 * see also: the-art-of-web.com/php/sortarray/
 * @param array $data input-array
 * @param string|array $fields array-keys
 * @license Public Domain
 * @return array
 */
function sortArray( $data, $field )
{
    $field = (array) $field;
    uasort( $data, function($a, $b) use($field) {
        $retval = 0;
        foreach( $field as $fieldname )
        {
            if( $retval == 0 ) $retval = strnatcmp( $a[$fieldname], $b[$fieldname] );
        }
        return $retval;
    } );
    return $data;
}


// example call, sort by 'growth' first and by 'country_code' afterwards
// this would be equal to a MySQL 'ORDER BY `growth` ASC, `country_code` ASC'
foreach( $countryArray as &$item )
{
    $item['countries'] = sortArray( $item['countries'], array( 'growth', 'country_code' ) );
}
0

Via a foreach() loop, use array destructuring syntax to modify the countries data by reference. In the loop body, call usort() and order the subarray rows by growth in a descending direction.

Code: (Demo)

foreach ($array as ['countries' => &$countries]) {
    usort($countries, fn($a, $b) => $b['growth'] <=> $a['growth']);
}
var_export($array);

The same technique can be functionally styled with array_map() to teturn a new mutated copy of the data.

Code: (Demo)

var_export(
    array_map(
        function ($set) {
            usort($set['countries'], fn($a, $b) => $b['growth'] <=> $a['growth']);
            return $set;
        },
        $array
    )
);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.