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',
    ),
  ),
)
3
  • Out of curiosity, how is the array being generated? Commented Nov 11, 2013 at 17:05
  • 1
    I have a SQL query that returns the array. Commented Nov 11, 2013 at 17:07
  • Maybe it's much easier to organize data by SQL grouping. Commented Nov 11, 2013 at 17:23

4 Answers 4

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);
Sign up to request clarification or add additional context in comments.

Comments

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;
        }
    )
);

Comments

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

3 Comments

@mickmackusa Just change $outputElement[] = $element; to $outputElement[] = $element['City']; problem solved
@mickmackusa A "thank you" would be nice.
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.
-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

1 Comment

This answer is incorrect because it only allows one city per subset. Proof: 3v4l.org/aDqFQ

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.