在php中将数组显示为树结构

I have an array:

Array
(
    [0] => dir0|file0.txt
    [1] => dir0|file1.txt
    [2] => dir1|file2.txt
    [3] => dir1|filea.txt
    [4] => dir2|fileb.txt
)

I would like it to be displayed as a tree, such as:

dir0
  file0.txt
  file1.txt
dir1 
  file2.txt
  filea.txt
dir2
  fileb.txt

Can any one explain how I can do that?

Edit: Updated for multidimentional array:

$paths[0][0] = 'dir0|file0.txt';
$paths[0][1] = 400;
$paths[1][0] = 'dir0|filea.txt';
$paths[1][1] = 500;
$paths[2][0] = 'dir1|file1.txt';
$paths[2][1] = 600;
$paths[3][0] = 'dir1|fileb.txt';
$paths[3][1] = 700;
$paths[4][0] = 'dir2|filec.txt';
$paths[4][1] = 700;

I would like the output to be:

dir0 (900)
  file0.txt (400)
  filea.txt (500)
dir1 (1300)
  file1.txt(600)
  fileb.txt (700)
dir2 (700)
  filec.txt (700)

The values need to be added and displayed in root.

The best way would be to reformat the array so the keys were the directories, and the array values were arrays containing file names, like so:

$array = array( ..);
$reformatted = array();
foreach( $array as $k => $v) {
    list( $key, $value) = explode( '|', $v);
    if( !isset( $reformatted[$key])) 
        $reformatted[$key] = array();
    $reformatted[$key][] = $value;
}

Then you just have to iterate over the new array, like so:

foreach( $reformatted as $dir => $files) {
    echo $dir . "
";
    foreach( $files as $file)
        echo "\t" . $file . "
";
}

This outputs:

dir0
    file0.txt
    file1.txt
dir1
    file2.txt
    filea.txt
dir2
    fileb.txt

Note that this will only work for plain text environment (such as <pre></pre>, like in the demo). Otherwise, you'll need to use <br /> instead of for line breaks, or use an ordered or unordered list.

For HTML output, use this, whose output can be seen here

echo '<ul>';
foreach( $reformatted as $dir => $files) {
    echo "<li>$dir</li>";
    echo '<ul>';
    foreach( $files as $file)
        echo "<li>$file</li>";
    echo '</ul>';
}
echo '</ul>';

Generates:

  • dir0
    • file0.txt
    • file1.txt
  • dir1
    • file2.txt
    • filea.txt
  • dir2
    • fileb.txt

For your updated array, here is the solution:

$reformatted = array(); $weights = array();
foreach( $paths as $k => $v) {
    list( $key, $value) = explode( '|', $v[0]);

    if( !isset( $reformatted[$key])) 
        $reformatted[$key] = array();

    if( !isset( $weights[$key]))
        $weights[$key] = 0;

    $reformatted[$key][] = array( $value, $v[1]);
    $weights[$key] += $v[1];    
}

foreach( $reformatted as $dir => $files) {
    echo $dir . ' (' . $weights[$dir] . ")
";
    foreach( $files as $file)
        echo "\t" . $file[0] . ' (' . $file[1] . ")
";
}

This outputs:

dir0 (900)
    file0.txt (400)
    filea.txt (500)
dir1 (1300)
    file1.txt (600)
    fileb.txt (700)
dir2 (700)
    filec.txt (700)

I'll leave it up to you to translate that into HTML if necessary.

You want to use a loop and do this.

 <?php
  $directories = array();
  foreach($arr as $val)
  {
     $pair = explode('|', $val);
     if(!isset($directories[$pair[0]])) { $directories[$pair[0]] = array(); }
     $directories[$pair[0]][] = $pair[1];
  }
  print_r($directories);

That will reorganize your array and then print_r it, showing you the new structure. Then you can do this:

    <?php
    foreach($directories as $directory => $files)
    {
      echo "$directory<br><ul>";
      foreach($files as $file)
      {
          echo "<li>$file</li>";
      }
      echo "</ul>";
  }