将每行包含3个元素的数组转换为具有3个层级的分层数组。

5

我有一个长这样的数组:

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

我正在尝试将这个数组分组成一个新的多维数组结构,以便输出类似于:
Continent
    - Country Name    
      -- Cities under Every Country

精确的期望结果:

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',
    ),
  ),
)

出于好奇,这个数组是如何生成的? - maiorano84
1
我有一个SQL查询,它返回数组。 - raeq
也许通过SQL分组更容易组织数据。 - sbrbot
可能是如何在PHP中将多维数组“展平”为简单数组?的重复问题。 - Prasanth Bendra
标题有误导性。问题是将一个多维数组转换为另一个具有不同结构的多维数组。 - faintsignal
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);

1
还有几种替代方法:
在没有主体的foreach()中使用“数组解构”来填充分层结构(演示)(更多关于该技术的信息)。
$result = [];
foreach (
    $array as
    [
        'Continent' => $a,
        'Country' => $b,
        'City' => $result[$a][$b][]
    ]
);
var_export($result);

使用array_reduce()来避免在全局范围内声明结果变量。(演示)
var_export(
    array_reduce(
        $array,
        function($result, $row) {
            $result[$row['Continent']][$row['Country']][] = $row['City'];
            return $result;
        }
    )
);

0
这个解决方案怎么样?
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);

@mickmackusa 只需将 $outputElement[] = $element; 更改为 $outputElement[] = $element['City']; 问题解决了。 - Peter de Groot
@mickmackusa 能说一声"谢谢"吗? - Peter de Groot
Stack Overflow不会做“谢谢”的回复。但是同样的,你可以感谢我提醒你的答案并不是最好的版本。我知道你的脚本在做什么,但是很多PHP开发者可能不理解它的工作原理,因此他们可能不会使用它。 - mickmackusa

-1

我认为你只需要在数组中循环,并使用一些值作为键,另一些值作为值来创建一个新的数组,例如:

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

实时示例


这个答案是不正确的,因为它只允许每个子集有一个城市。证明:https://3v4l.org/aDqFQ - mickmackusa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接