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

时间:2014-08-28 18:31:50

标签: php multidimensional-array filepath

拥有此文件路径数组

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

2 个答案:

答案 0 :(得分:0)

最后,我在a similar problemarray_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',
      ),
    ),
  ),
)