将数组转换为ul li列表

时间:2014-05-20 19:17:24

标签: php html arrays multidimensional-array html-lists

所以我有一个文件路径看起来像这样的文件。 ./CatDV/S1/SFX/steam/6004_90_04 LargeHeadlightSm.wav ./CatDV/S1/SFX/steam/AirHissPressureRe HIT032001.wav ./CatDV/S1/SFX/steam/Impact_Metal_Bullet_Hit(1).wav ./CatDV/S1/SFX/steam/Impact_Metal_Bullet_Hit.wav ./CatDV/S1/SFX/steam/6004_94_02 LargeHeavyGlassS.wav ./CatDV/S1/SFX/steam/Impact_Glass_Smash.wav ./CatDV/S1/SFX/steam/AirReleaseHeavyAi HIT030701.wav ./CatDV/S1/SFX/steam/SDR02_15SCIF RhythmicRever.wav ./CatDV/S1/SFX/steam/VAL02_08CRSH GlassBreaking.wav ./CatDV/S1/SFX/steam/AirReleaseLargeAi HIT030601.wav ./CatDV/S1/SFX/steam/SDR02_14SCIF Rhythmic3Beat.wav ./CatDV/S1/SFX/steam/6004_94_01 LargeGlassSmash.wav

我想把所有这些分成ul li list.so

> CatDV
    > S1
        > SFX
            > steam
                > filename.extension

等等......

这是我正在使用的阵列。我用下面的函数输出了它。

array(1) {
  [""]=>
  array(1) {
    ["CatDV"]=>
    array(1) {
      ["S1"]=>
      array(1) {
        ["SFX"]=>
        array(1) {
          ["steam"]=>
          array(12) {
            ["6004_90_04 LargeHeadlightSm.wav"]=>
                string(52) "./CatDV/S1/SFX/steam/6004_90_04 LargeHeadlightSm.wav"
            ["AirHissPressureRe HIT032001.wav"]=>
                string(52) "./CatDV/S1/SFX/steam/AirHissPressureRe HIT032001.wav"
            ["Impact_Metal_Bullet_Hit(1).wav"]=>
                string(51) "./CatDV/S1/SFX/steam/Impact_Metal_Bullet_Hit(1).wav"
            ["Impact_Metal_Bullet_Hit.wav"]=>
                string(48) "./CatDV/S1/SFX/steam/Impact_Metal_Bullet_Hit.wav"
            ["6004_94_02 LargeHeavyGlassS.wav"]=>
               string(52) "./CatDV/S1/SFX/steam/6004_94_02 LargeHeavyGlassS.wav"
            ["Impact_Glass_Smash.wav"]=>
               string(43) "./CatDV/S1/SFX/steam/Impact_Glass_Smash.wav"
            ["AirReleaseHeavyAi HIT030701.wav"]=>
               string(52) "./CatDV/S1/SFX/steam/AirReleaseHeavyAi HIT030701.wav"
            ["SDR02_15SCIF RhythmicRever.wav"]=>
               string(51) "./CatDV/S1/SFX/steam/SDR02_15SCIF RhythmicRever.wav"
            ["VAL02_08CRSH GlassBreaking.wav"]=>
               string(51) "./CatDV/S1/SFX/steam/VAL02_08CRSH GlassBreaking.wav"
            ["AirReleaseLargeAi HIT030601.wav"]=>
              string(52) "./CatDV/S1/SFX/steam/AirReleaseLargeAi HIT030601.wav"
            ["SDR02_14SCIF Rhythmic3Beat.wav"]=>
              string(51) "./CatDV/S1/SFX/steam/SDR02_14SCIF Rhythmic3Beat.wav"
            ["6004_94_01 LargeGlassSmash.wav"]=>
              string(51) "./CatDV/S1/SFX/steam/6004_94_01 LargeGlassSmash.wav"
          }
        }
      }
    }
  }
}

现在我把它转换成了一个ul li列表,我可以输出到我的html中并将其设置为样式。

function arch_list($output) {
// //Conditional for Archives Page
    $data = file(get_template_directory_uri() . '/js/angular/data/list_test.txt', FILE_IGNORE_NEW_LINES);

    $path = array('data' => $data);
    $output = array();
    foreach ($path['data'] as $d) {
        $out = preg_split('/(\.)*\//', $d);
        $outArr = $d;
        for ($i = count($out) - 1; $i >= 0; $i--) {             
            $outArr = array($out[$i] => $outArr);               
        }
        // return $outArr;
        $output = array_merge_recursive($output, $outArr);

    }
    return $output;
}   

任何帮助表示赞赏! 感谢。

4 个答案:

答案 0 :(得分:6)

我已经在@ hakre的答案中重构了那个令人难以置信的代码,但是稍微不那么敬畏。它使用相同的aglorithm:

$file = './CatDV/S1/SFX/steam/6004_90_04 LargeHeadlightSm.wav
./CatDV/S1/SFX/steam/AirHissPressureRe HIT032001.wav
./CatDV/S1/SFX/steam/Impact_Metal_Bullet_Hit(1).wav
./CatDV/S1/SFX/steam/Impact_Metal_Bullet_Hit.wav
./CatDV/S1/SFX/steam/6004_94_02 LargeHeavyGlassS.wav
./CatDV/S1/SFX/steam/Impact_Glass_Smash.wav
./CatDV/S1/SFX/steam/AirReleaseHeavyAi HIT030701.wav
./CatDV/S1/SFX/steam/SDR02_15SCIF RhythmicRever.wav
./CatDV/S1/SFX/steam/VAL02_08CRSH GlassBreaking.wav
./CatDV/S1/SFX/steam/AirReleaseLargeAi HIT030601.wav
./CatDV/S1/SFX/steam/SDR02_14SCIF Rhythmic3Beat.wav
./CatDV/S1/SFX/steam/6004_94_01 LargeGlassSmash.wav';

这些是内部功能,您无需直接致电。

function splitIntoPaths($string) {
    $paths = array();
    foreach (explode("\n", $string) as $line) {
        $node = &$paths;
        foreach (explode("/", $line) as $segment) {
            if (!isset($node[$segment])) {
                $node[$segment] = array();
            }
            $node = &$node[$segment];
        }
        $node = $line;
    }
    return $paths;
}

function createListFromArray(array $array) {
    $return = "<ul>";
    foreach ($array as $key => $value) {
        $return .= "<li>" . $key;
        if (is_array($value)) {
            $return .= createListFromArray($value);
        }
        $return .= "</li>";
    }
    return $return . "</ul>";
}

这是为你工作的功能,给你一个字符串。

function createTree($string) {
    $paths = splitIntoPaths($string);
    return createListFromArray($paths);
}

用法:

$tree = createTree($file);

答案 1 :(得分:3)

由于您不知道树的深度,您可以使用递归函数调用来显示ul / li树。这实际上与this yesterdays question类似,但是,您在此处有不同的决策点:

$file = './CatDV/S1/SFX/steam/6004_90_04 LargeHeadlightSm.wav
./CatDV/S1/SFX/steam/AirHissPressureRe HIT032001.wav
./CatDV/S1/SFX/steam/Impact_Metal_Bullet_Hit(1).wav
./CatDV/S1/SFX/steam/Impact_Metal_Bullet_Hit.wav
./CatDV/S1/SFX/steam/6004_94_02 LargeHeavyGlassS.wav
./CatDV/S1/SFX/steam/Impact_Glass_Smash.wav
./CatDV/S1/SFX/steam/AirReleaseHeavyAi HIT030701.wav
./CatDV/S1/SFX/steam/SDR02_15SCIF RhythmicRever.wav
./CatDV/S1/SFX/steam/VAL02_08CRSH GlassBreaking.wav
./CatDV/S1/SFX/steam/AirReleaseLargeAi HIT030601.wav
./CatDV/S1/SFX/steam/SDR02_14SCIF Rhythmic3Beat.wav
./CatDV/S1/SFX/steam/6004_94_01 LargeGlassSmash.wav';

$tree = [];
foreach (explode("\n", $file) as $line) {
    $node = &$tree;
    foreach (explode('/', $line) as $segment) {
        $node = &$node[$segment];
    }
    $node = $line;
    unset($node);
}

call_user_func(function ($array) {
    $ul = function ($array) use (&$ul) {
        echo '<ul>', !array_walk($array, function ($child, $key) use ($ul) {
            echo '<li>', $key, is_array($child) ? $ul($child) : ''
            , '</li>';
        }, $array), '</ul>';
    };
    $ul($array);
}, $tree);

请注意,这个包含自包含的示例代码(Demo)还包含一种不同的方法来构建$tree数组,但与您的方式略有不同(主要区别在于我没有'使用array_merge_recursive(),而是在遍历$tree数组时使用引用自行合并。

对于递归,一旦你理解了递归函数调用是如何工作的,它就非常直接:解决一个列表的问题并将解决方案包装到函数中。如果列出条目有子项,则插入新列表。使用相同的功能。

输出(美化):

<ul>
    <li>.
        <ul>
            <li>CatDV
                <ul>
                    <li>S1
                        <ul>
                            <li>SFX
                                <ul>
                                    <li>steam
                                        <ul>
                                            <li>6004_90_04 LargeHeadlightSm.wav</li>
                                            <li>AirHissPressureRe HIT032001.wav</li>
                                            <li>Impact_Metal_Bullet_Hit(1).wav</li>
                                            <li>Impact_Metal_Bullet_Hit.wav</li>
                                            <li>6004_94_02 LargeHeavyGlassS.wav</li>
                                            <li>Impact_Glass_Smash.wav</li>
                                            <li>AirReleaseHeavyAi HIT030701.wav</li>
                                            <li>SDR02_15SCIF RhythmicRever.wav</li>
                                            <li>VAL02_08CRSH GlassBreaking.wav</li>
                                            <li>AirReleaseLargeAi HIT030601.wav</li>
                                            <li>SDR02_14SCIF Rhythmic3Beat.wav</li>
                                            <li>6004_94_01 LargeGlassSmash.wav</li>
                                        </ul>
                                    </li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

答案 2 :(得分:0)

试试这个

<?php
    $fileToOpen="/js/angular/data/list_test.txt";

    function arch_list($fileToOpen) {
        if(file_exists($fileToOpen)){
            $file=fopen($fileToOpen,"r");
            while($line = fgets($file)){
               //We have a line of the file,split it up
               $directories=explode("/",$line);
                //Remove the period, it will be the first element in the array
               $directories=array_shift($directories);
               //Add this set of directories to a parent array
               $allDirectories[]=$directories;
            }
            fclose($fileToOpen);

        }//End of opening file

        //We now have a multidimensional array, 
        //An array holding arrays with each set of directories.
        if(!empty($allDirectories)){
           foreach($allDirectories as $directory){
               $fullString.="<ul class='your-class'>";
               foreach($directory as $pathway){
                   //We have each single item in a directory path
                     $fullString.="<li>".$pathway."</li>";
               }
               $fullString.="</ul>";
           }
        }
        return $fullString;
    }

    echo arch_list($fileToOpen);


?>

答案 3 :(得分:0)

我正在看@hakre的。它将最低级别的key =&gt;值设为2&lt; li&gt;,我认为这不是想要的。我的解决方案(假设有一个多维数组):

$arrayvar = array("blank?"=>
  array("CatDV"=>
    array("S1"=>
      array("SFX"=>
        array("steam"=>
          array("6004_90_04 LargeHeadlightSm.wav"=>
            "./CatDV/S1/SFX/steam/6004_90_04 LargeHeadlightSm.wav", 
                "AirHissPressureRe HIT032001.wav"=>
            "./CatDV/S1/SFX/steam/AirHissPressureRe HIT032001.wav"))))));
makeul($arrayvar);            

function makeul($avar) { // make ul
  if (!is_array($avar)) exit("Err: not an array");
  echo("<ul>");
  reset($avar); while(true) { // loop through array
    $key = key($avar);     
    if (is_null($key)) break; // if NULL, end of loop
    $val = $avar[$key];
    if (is_scalar($val)) zecho("<li>$key=>$val</li> ");
    else { zecho("<li>$key"); makeul($val); zecho("</li>"); } // recurse
    next($avar); } 
  zecho("</ul>");
  }
function zecho($param) { // echo with br & \n
  echo $param, "<br />\n"; 
  }

编辑(for hakre):我从你的代码中学到了很多东西,谢谢你,但这不是不必要的模糊吗?
以下是不是更好,更清楚?

$tree = ..
makeul($tree, '');

function makeul($val, $key) { 
  if ($key <> "") echo "<li>$key\n";
  if (is_array($val)) { 
    echo("<ul>"); array_walk($val, 'makeul'); echo("</ul>\n"); }
  else {
    echo("=>$val<br />\n"); }
  if ($key <> "") echo "</li>";
  }