如何从文件路径数组创建HTML组列表


How to create a HTML group list from array of file paths?

具有此文件路径数组

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分组列表元素?最后的分组必须看起来像:

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循环、array_walk()和array_requeste(),但无法实现我想要的。

编辑

以下是我最后一次尝试,以满足那些对我自己寻找解决方案的努力持怀疑态度的人,然后再问:

$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?
    }
}

最后,我找到了一个类似问题的解决方案和array_marge_recurive()的组合。感谢所有响应者的努力。

有几种技术可以完成这项工作。我将提供三种方法,它们将使用以下输入并提供相同的输出(我的文章底部的输入和输出)。

代码:#1-不修改的堆叠方法通过参考演示链接

$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-递归方法演示链接

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:-通过参考修改演示链接的堆叠方法

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