拥有此文件路径数组
paths: Array
(
[0] => folder1/content/file1.php
[1] => folder1/content/file2.php
[2] => folder1/edit/file1.php
[3] => folder1/edit/file2.php
[4] => folder1/pagination/file1.php
[5] => folder1/pagination/file2.php
[6] => folder1/toolbar/file1.php
[7] => folder1/toolbar/file2.php
[8] => folder2/cms/html/file1.php
[9] => folder2/cms/html/file2.php
)
如何将内存高效地解析为HTML-grouped-list-element?最终的分组必须如下:
final: Array
(
[folder1] => Array
(
[content] => Array
(
[0] => file1.php
[1] => file2.php
)
[edit] => Array
(
[0] => file1.php
[1] => file2.php
)
[pagination] => Array
(
[0] => file1.php
[1] => file2.php
)
[toolbar] => Array
(
[0] => file1.php
[1] => file2.php
)
)
[folder2] => Array
(
[cms] => Array
(
[html] => Array
(
[0] => file1.php
[1] => file2.php
)
)
)
)
我注意到路径的深度可变,并且遇到了这个问题。解析例程不能固定到指定的递归级别。它反过来遍历文件路径,直到文件名保留为止,并将此文件添加到数组中。 我尝试了几种方法 - foreach loop,array_walk()和array_reduce(),但无法达到我想要的效果。
修改
这是我最后的尝试,以满足那些对我在寻求解决方案之前努力的疑问:
$groups = [];
foreach ($paths as $path)
{
$pieces = explode(DIRECTORY_SEPARATOR, $path);
if (!array_key_exists(($first = array_shift($pieces)), $groups))
{
$groups[$first] = [];
// Mhm ... how to recoursively nest further
// arrays for every path level left?
}
}
答案 0 :(得分:0)
最后,我在a similar problem和array_merge_recursive()的解决方案的组合中找到了解决方案。 感谢所有响应者的努力。
答案 1 :(得分:0)
有几种技术可以完成这项工作。我将提供三种方法,它们将使用以下输入并提供相同的输出(我的帖子底部的输入和输出)。
代码:#1 - 没有通过引用修改的堆叠方法Demo Link
$result = [];
foreach ($paths as $path) {
$entries = array_reverse(explode("/", $path)); // use DIRECTORY_SEPARATOR for greater utility
foreach ($entries as $i=>$entry) {
if (!$i) { // if index value is zero
$item=[$entry]; // store filename as indexed element
} else {
$item[$entry][key($item)] = array_shift($item); // store previous element in new level using new entry and previous key; while destroying previous element
}
}
$result = array_merge_recursive($result, $item); // merge new associative array with existing results
}
var_export($result);
代码#2 - 递归方法Demo Link
function pathToNestedArray($path, $separator = "/") { // use DIRECTORY_SEPARATOR for greater utility
$halves = explode($separator, $path, 2); // maximum explosion is 2 elements
if (!isset($halves[1])) return [$path]; // no folder to nest into, append as indexed element (Done)
return [$halves[0] => pathToNestedArray($halves[1])]; // apply level's key value and recurse
}
$result = [];
foreach ($paths as $path) {
$result = array_merge_recursive($result, pathToNestedArray($path)); // merge new associative array with existing results
}
var_export($result);
代码#3: - 通过引用修改的堆叠方法Demo Link
$result = [];
foreach ($paths as $path) {
$temp = &$result; // make $result modifiable by reference
$entries = explode("/", $path); // use DIRECTORY_SEPARATOR for greater utility
$file = array_pop($entries); // remove the file from the array
foreach ($entries as $folder) {
$temp = &$temp[$folder]; // store folder as key
}
$temp[] = $file; // story indexed element (file) to temp reference
unset($temp); // destroy the reference
}
var_export($result);
输入:
$paths = [
"fileZ.php",
"folder1/content/file1.php",
"folder1/content/file2.php",
"folder1/edit/file1.php",
"folder1/edit/file2.php",
"folder1/pagination/file1.php",
"folder1/pagination/file2.php",
"folder1/toolbar/file1.php",
"folder1/toolbar/file2.php",
"folder2/cms/html/file1.php",
"folder2/cms/html/file2.php"
];
输出:
array (
0 => 'fileZ.php',
'folder1' =>
array (
'content' =>
array (
0 => 'file1.php',
1 => 'file2.php',
),
'edit' =>
array (
0 => 'file1.php',
1 => 'file2.php',
),
'pagination' =>
array (
0 => 'file1.php',
1 => 'file2.php',
),
'toolbar' =>
array (
0 => 'file1.php',
1 => 'file2.php',
),
),
'folder2' =>
array (
'cms' =>
array (
'html' =>
array (
0 => 'file1.php',
1 => 'file2.php',
),
),
),
)