【问题标题】:How to create a HTML group list from array of file paths?如何从文件路径数组创建 HTML 组列表?
【发布时间】:2014-10-22 17:17:08
【问题描述】:

拥有这个文件路径数组

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

【问题讨论】:

  • 前后数据对我们很有帮助,但我们也需要看你的代码。到目前为止,您尝试过什么?
  • 不知道你说的前后数据是什么意思。我的尝试看起来与user3659034 foreach 循环的建议完全相同。唯一的区别是我用 array_walk() 和 array_reduce() 替换了 foreach 循环,以防止通过 foreach 循环的数组的内存昂贵的重复。
  • 您提供了处理之前收到的数据,以及处理之后需要的结果。您应该发布您的代码,因为它会与下面的任何建议有所不同。它证明您尝试了某些东西,并且将来可能会删除下面的答案,从而使您的问题不完整。此外,您可能比您想象的更接近解决方案。
  • 生成文件列表的代码与此问题无关。我阅读了一个文件夹的内容以获取其中的文件列表,并希望从中创建一个分组下拉列表。而已。上面提供的数据是我所拥有的以及问题的基础。为什么我必须证明我尝试过什么?我知道我尝试了几种方法,每次新尝试都会覆盖以前的实现。所以最后的尝试看起来与下面 user3659034 的建议没有太大不同。
  • 我不关心你如何获得你想要操作的数据——你说得对,这无关紧要。我想看看你是如何试图得到你的结果的。您会注意到 user3659034 在下面删除了他的答案,这就是您的尝试很重要的原因。我并不是想给你带来困难 - 我实际上是在努力确保你得到帮助,并且这个问题和答案是未来有用的资源。

标签: php multidimensional-array filepath


【解决方案1】:

最后我在a similar problemarray_merge_recursive() 的解决方案组合中找到了解决方案。 感谢所有响应者的努力。

【讨论】:

    【解决方案2】:

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

    代码:#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',
          ),
        ),
      ),
    )
    

    【讨论】:

    • @user1014412 我已经为您提供了一套全面的解决方案(这样未来的研究人员就不需要追逐链接了)。除非我的回答有什么不合适的地方,否则请打上绿色的勾,这样您的问题就被视为已解决。
    猜你喜欢
    • 2019-08-11
    • 2017-02-06
    • 2011-02-24
    • 2018-03-08
    • 2012-11-23
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    相关资源
    最近更新 更多