5

I have an array that looks like this:

[98] => Array
(
    [City] => Caracas
    [Country] => Venezuela
    [Continent] => Latin America
)

[99] => Array
(
    [City] => Cairo
    [Country] => Egypt
    [Continent] => Middle East
)

[105] => Array
(
    [City] => Abu Dhabi
    [Country] => United Arab Emirates
    [Continent] => Middle East
)

[106] => Array
(
    [City] => Dubai
    [Country] => United Arab Emirates
    [Continent] => Middle East
)

[107] => Array
(
    [City] => Montreal
    [Country] => Canada
    [Continent] => North America
)

I am trying to group this array into a new multi-dimensional array structure, so that it outputs something like:

Continent
    - Country Name    
      -- Cities under Every Country

Exact desired result:

array (
  'Latin America' => 
  array (
    'Venezuela' => 
    array (
      0 => 'Caracas',
    ),
  ),
  'Middle East' => 
  array (
    'Egypt' => 
    array (
      0 => 'Cairo',
    ),
    'United Arab Emirates' => 
    array (
      0 => 'Abu Dhabi',
      1 => 'Dubai',
    ),
  ),
  'North America' => 
  array (
    'Canada' => 
    array (
      0 => 'Montreal',
    ),
  ),
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
raeq
  • 971
  • 4
  • 15
  • 36

4 Answers4

10
$array = array(
    98 => array(
        'City' => 'Caracas',
        'Country' => 'Venezuela',
        'Continent' => 'Latin America',
    ),
    99 => array(
        'City' => 'Cairo',
        'Country' => 'Egypt',
        'Continent' => 'Middle East',
    ),
    105 => array(
        'City' => 'Abu Dhabi',
        'Country' => 'United Arab Emirates',
        'Continent' => 'Middle East',
    ),
    106 => array(
        'City' => 'Dubai',
        'Country' => 'United Arab Emirates',
        'Continent' => 'Middle East',
    ),
    107 => array(
        'City' => 'Montreal',
        'Country' => 'Canada',
        'Continent' => 'North America',
    )
);

$newArray = array();
foreach ($array as $row)
{
   $newArray[$row['Continent']][$row['Country']][] = $row['City'];
}

print_r($newArray);
Raphaël Malié
  • 3,912
  • 21
  • 37
1

A couple more alternative approaches:

Use "array destructuring" in a body-less foreach() to populate the hierarchical structure (Demo) (Further about the technique)

$result = [];
foreach (
    $array as
    [
        'Continent' => $a,
        'Country' => $b,
        'City' => $result[$a][$b][]
    ]
);
var_export($result);

Use array_reduce() to avoid declaring a result variable in the global scope. (Demo)

var_export(
    array_reduce(
        $array,
        function($result, $row) {
            $result[$row['Continent']][$row['Country']][] = $row['City'];
            return $result;
        }
    )
);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
0

What about this solution:

function arrayToMultiDimensionalArray(array $elements, array $dimensions)
{
    $output = [];

    foreach ($elements as $element) {
        $outputElement =& $output;

        // Foreach to build up the dimensions
        foreach ($dimensions as $dimension) {
            $outputElement =& $outputElement[$element[$dimension]];
        }

        $outputElement[] = $element['City'];
    }

    return $output;
}

$dimensions = ['Continent', 'Country'];

$tree = arrayToMultiDimensionalArray($array, $dimensions);
Peter de Groot
  • 829
  • 7
  • 12
  • @mickmackusa Just change $outputElement[] = $element; to $outputElement[] = $element['City']; problem solved – Peter de Groot Apr 03 '23 at 08:53
  • @mickmackusa A "thank you" would be nice. – Peter de Groot Apr 03 '23 at 09:11
  • Stack Overflow doesn't do "thank you"s. Just the same, you can thank me for bringing to your attention that your answer wasn't (and still isn't) the best version of itself. I know what your script is doing, but there will be many PHP developers who won't and they might not use it because they don't understand how it works. – mickmackusa Apr 03 '23 at 09:16
-1

I think you just need to loop in your array and create a new one using some values as keys and some other as value, for example

$new_array = array();
foreach($array as $val)
{ 
     $new_array[$val['Continent']][$val['Country']] = array('City' => $val['City']);
}  

Live Sample

Fabio
  • 23,183
  • 12
  • 55
  • 64