Reputation: 87
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',
],
]
Upvotes: 2
Views: 154
Reputation: 47991
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
)
);
Upvotes: 0
Reputation: 29932
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' ) );
}
Upvotes: 0