我需要有关阵列转换的帮助。我有一个看起来像这样的平面阵列:
Array
(
[0] => av_one_third
[1] => av_icon_box
[2] => /av_icon_box
[3] => av_button
[4] => av_icon_box
[5] => /av_icon_box
[6] => /av_one_third
)
此数组的值实际上是来自类似xml的结构的标记。我现在需要的是将此数组转换为类似于以下结构的嵌套数组:
[0] => Array
(
[tag] => av_one_third
[content] => Array
(
[1] => Array
(
[tag] => av_icon_box
[content] => Array
(
)
)
[2] => Array
(
[tag] => av_button
[content] => Array
(
)
)
[3] => Array
(
[tag] => av_icon_box
[content] => Array
(
)
)
)
)
etc
有一种简单的方法吗?我的第一个想法是将数组转换为xml字符串并使用phps本机XML函数之一,但问题是自闭标签没有标记为这样。在上面的例子中,av_button标签没有关闭标签抛出我试过的xml解析函数。
一些额外要求: - 元素可以容纳任意数量的孩子 - 最终数组必须保持正确的顺序
是否有可以轻松解决此问题的智能阵列排序功能? 将不胜感激任何暗示!
最好的问候:)
答案 0 :(得分:1)
您的数组具有编码层次结构的典型平面结构。但只有你在那里修复错误。
它基本上与以下列表中的PHP代码一样,包括异常告诉数据中的错误,以便您可以修复数据(您可以在此网站上找到类似示例,例如查看{{3中的链接问题}}):
初始化树阵列中的根条目。在那里你可以添加孩子。
$tree = ['children' => []];
创建一个指向树的指针数组,其第一个元素(级别0)指向树的根元素:
$pointers = [&$tree];
现在查看数据中的每一行:
foreach ($data as $index => $line) {
决定该行是否关闭并存储决策结果:
$close = '/' === $line[0];
存储指针的当前计数:
$count = count($pointers);
如果该行没有关闭,请打开一个新元素并继续:
$pointers[$count] = ['tag' => $line, 'children' => []];
$pointers[$count - 1]['children'][] = & $pointers[$count];
continue;
如果该行确实关闭,请验证标记名是否匹配,如果是,则删除最后创建的指针:
if ($count === 1) {
throw new RuntimeException('Can not close on lowest level.');
}
$name = $pointers[$count - 1]['tag'];
if ($name !== substr($line, 1)) {
throw new RuntimeException(
"Invalid closing element <$line> (line #$index) in <$name>"
);
}
array_pop($pointers);
在处理完所有行之后,可以删除所有指针:
unset($pointers);
结果是可以在根节点中的第一个子节点中找到的数组。它可以分配给变量,然后可以删除不需要的引用:
$result = &$tree['children'][0];
unset($tree);
print_r($result);
如果数据正确,则为示例输出:
Array
(
[tag] => av_one_third
[children] => Array
(
[0] => Array
(
[tag] => av_icon_box
[children] => Array
(
)
)
[1] => Array
(
[tag] => av_button
[children] => Array
(
)
)
[2] => Array
(
[tag] => av_icon_box
[children] => Array
(
)
)
)
)