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:
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.