从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中的数组生成多维数组?的主要内容,如果未能解决你的问题,请参考以下文章