从php中的数组生成多维数组?

Posted

技术标签:

【中文标题】从php中的数组生成多维数组?【英文标题】:Generate multi-dimensional array from an array in php? 【发布时间】:2022-01-17 10:28:24 【问题描述】:

我有一个关联数组列表如下:

[
"country" => "AU",
"state" => "VIC",
"suburb" => "Carlton",
"precedence" => ["country", "state", "suburb"]
]

我想要一个新的多维数组,如下所示,其中元素根据第一个数组上的 precedence 键定义的顺序嵌套:

[
 "country" => [
  "AU" => [
    "state" => [
      "VIC" => [
        "suburb" => "Carlton
      ]
     ]
    ]
   ]
]

以上只是一个示例,我想要一个适用于任何类型数组的通用解决方案。所有输入数组唯一满足的一个条件是它们将有一个 precedence 元素,表示需要生成输出数组的顺序。

我尝试了一些递归解决方案,但它没有按预期工作,并且出现 php 致命错误:允许的内存大小为 1073741824 字节已用尽(看起来它正在无限运行):

function generateArray(&$array)
    
        foreach ($array['precedence'] as $key => $property) 
            if ($key == sizeof($array['precedence']) - 1) 
                return [$property => $array[$property]];
             else 
                return generateAssetConfig($array);
            
        
    

【问题讨论】:

为什么需要制作这个结构?如果您需要 state 原样怎么办,如果它是这种结构,那么您将不知道它是键还是所有嵌套后的最终值。 【参考方案1】:

您可以循环优先部分的反转项目。

如果结果数组中还没有项目,则添加第一个键 => 值对。

否则将当前结果包装在一个多维数组中,如果将迭代设置为外部键,则将当前值设置为,并将值(对于源数组中的该键)与当前结果一起包装在第二个数组中。

$source = [
    "country" => "AU",
    "state" => "VIC",
    "suburb" => "Carlton",
    "precedence" => ["country", "state", "suburb"]
];

function generateArray($array)

    $result = [];
    foreach(array_reverse($array["precedence"]) as $v) 
        $result =! $result ? [$v => $array[$v]] : [$v => [$array[$v] => $result]];
    
    return $result;


var_export(generateArray($source));

输出

array (
  'country' => 
  array (
    'AU' => 
    array (
      'state' => 
      array (
        'VIC' => 
        array (
          'suburb' => 'Carlton',
        ),
      ),
    ),
  ),
)

【讨论】:

谢谢大家!以下所有答案也是正确的,但我发现这个最简单,所以我投了赞成票。 哇,很棒的解决方案!我什至无法考虑这一点。干得好!【参考方案2】:

试试这个:

function generateNestedArray($arr) 
  $precedence = $arr['precedence'];
  $nestedArray = [];
  for ($i = count($precedence)-1; $i >= 0; $i--) 
    $key = $precedence[$i];
    if (!$nestedArray) 
      $nestedArray[$key] = $arr[$key];
     else 
      $nestedArray = [$key => [ $arr[$key]=> $nestedArray]];
    
   
  
  return $nestedArray;

【讨论】:

【参考方案3】:

这是一个递归算法:

<?php

$raw = [
    [
        "country" => "AU",
        "state" => "VIC",
        "suburb" => "Carlton",
        "precedence" => ["country", "state", "suburb"]
    ],
    [
        "country" => "AU",
        "state" => "NSW",
        "suburb" => "Sydney",
        "precedence" => ["country", "state", "suburb"]
    ]
];

function generateFromPrecedence($array)

    if (!isset($array['precedence']))
        throw new Exception('Precedence array does not exist');

    if (!empty(array_diff($array['precedence'], array_diff(array_keys($array), ['precedence']))))
        throw new Exception('Keys and precendence keys different');

    return generateStructure($array);


function generateStructure($array, $precedence = 0)

    if ($precedence == count($array['precedence'])-1)
        return [$array['precedence'][$precedence] => $array[$array['precedence'][$precedence]]];

    return [$array['precedence'][$precedence] => [$array[$array['precedence'][$precedence]] => generateStructure($array, ++$precedence)]];


$output = generateFromPrecedence($raw[0]);

var_dump($output);

输出:

array(1) 
["country"]=>
array(1) 
    ["AU"]=>
    array(1) 
    ["state"]=>
    array(1) 
        ["NSW"]=>
        array(1) 
        ["suburb"]=>
        string(6) "Sydney"
        
    
    


【讨论】:

【参考方案4】:

最简单的解决方案(递归函数):

function generateArrayRecursion($array, $precedenceIndex = 0) 
    $precedence = $array['precedence'];
    
    return [
        $precedence[$precedenceIndex] => $precedenceIndex === \count($precedence) - 1
            ? $array[$precedence[$precedenceIndex]]
            : [$array[$precedence[$precedenceIndex]] => generateArrayRecursion($array, $precedenceIndex + 1)]
    ];

替代解决方案(循环和数组引用):

function generateArray($array) 
    $precedence = $array['precedence'];
    $result = [];
    $lastKey = $precedence[count($precedence) - 1];

    $currentElement = &$result;
    foreach ($precedence as $key) 
        if ($key === $lastKey) 
            $currentElement[$key] = $array[$key];
         else 
            $currentElement[$key] = [$array[$key] => []];
            $currentElement = &$currentElement[$key][$array[$key]];
        
    
    
    return $result;

用法示例:

$array = [
    "country" => "AU",
    "state" => "VIC",
    "suburb" => "Carlton",
    "precedence" => ["country", "state", "suburb"]
];

var_dump(generateArrayRecursion($array));
var_dump(generateArray($array));

【讨论】:

以上是关于从php中的数组生成多维数组?的主要内容,如果未能解决你的问题,请参考以下文章

从 PHP 中的数组构建多维数组

如何从 PHP 中的多维关联数组中删除项目

如何从 PHP 中的多维数组中删除重复值

从php中的多维数组中删除重复值

PHP 从PHP中的多维数组中删除空项

循环多维数组以生成谷歌图表的多维数组