Reputation: 2337
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.
Upvotes: 2
Views: 3954
Reputation: 59709
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 . "\n";
foreach( $files as $file)
echo "\t" . $file . "\n";
}
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 \n
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:
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] . ")\n";
foreach( $files as $file)
echo "\t" . $file[0] . ' (' . $file[1] . ")\n";
}
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.
Upvotes: 5
Reputation: 11132
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>";
}
Upvotes: 1