Thread Verzeichnisbaum: Flaches Array mehrdimensional printen (13 answers)
Opened by root at 2005-03-26 12:20

coax
 2005-04-03 23:30
#52978 #52978
User since
2003-08-11
457 Artikel
BenutzerIn
[default_avatar]
Eine vollfunktionierende aber ineffiziente Version:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/usr/bin/perl

 use strict;
 use warnings;

 use Data::Dumper;

 our $DEBUG = 0;       # Debugging: Aus = 0; An = 1 oder 2
 our $SHIFTWIDTH = 4;

 # Simuliert Datenbankabfrage
 my(@rows) =  map { my %h; @h{ qw(id filename content content_type) } = @$_; \%h }
         [1, '/dir1/dir1.1/dir1.1.1/file1.1.1.1', 'bla bla bla',   'text'],
         [2, '/dir1/dir1.2/dir1.2.1/file1.2.1.1', 'blu bla blubb', 'text'],
         [4, '/dir1/file1',                       'blu bla bla',   'text'],
         [5, '/dir1/file2',                       'blu bla ble',   'text'],
         [3, '/dir2/dir2.1/dir2.1.1/file2.1.1.3', 'bli blu bla',   'text'],
         [6, 'file1',                             'bar bla blo',   'text'],
         [7, 'afile2',                            'another file',  'text'],
         [8, 'bfile2',                            'bnother file',  'text'];

 my $tree;
 while(my $row = shift @rows) {                             # jede Datenzeile
     $tree = process_data($row->{'filename'}, $row, $tree); # verarbeiten und Baum hinzufuegen
 }

 print Dumper($tree), '-'x25, "\n" if $DEBUG;

 print <<EOT1;
var TREE_ITEMS = [
EOT1

 # erzeuge JS-Code
 build_js_code($tree);

 print <<EOT2;
];
EOT2
 
 sub process_data {
     my($path, $row_data, $tree) = @_;

     $tree = {'type' => 'dir'} unless $tree;

     $path =~ s:^[\\/]::;

     my($super, $sub) = split /[\/\\]/, $path, 2;

     if($sub && $sub ne '') {
         $tree->{'items'}->{$super} = process_data($sub, $row_data, {'dir' => 1});
     } else {
         $tree->{'items'}->{$super} = {'file' => 1, 'data' => $row_data };
     }

     return $tree;
 }

 sub build_js_code {
     my $tree = shift;
     my $indent = shift || 1;
         foreach my $key (sort {return $a cmp $b if $tree->{'items'}->{$a}->{'dir'}
                                                 && $tree->{'items'}->{$b}->{'dir'};
                                return $a cmp $b if $tree->{'items'}->{$a}->{'file'}
                                                 && $tree->{'items'}->{$b}->{'file'};
                                return $tree->{'items'}->{$a}->{'dir'} ? -1 : 1;}
                          keys %{ $tree->{'items'} } ) {

         if( $tree->{'items'}->{$key}->{'dir'} ) {
             print ' ' x ($SHIFTWIDTH * $indent),
                   "['", $key, ", null,\n";
             build_js_code( $tree->{'items'}->{$key}, $indent + 1);
         } else {
             print ' ' x  ($SHIFTWIDTH * $indent),
                   "['", $key, "', '", $tree->{'items'}->{$key}->{'data'}->{'content'}, "']\n";
         }
     }
     
 }

Die erste rekursive Funktion bildet den Verzeichnisbaum in Perlstruktur die zweite sortiert den Baum und gibt den JS-Code aus (laesst sich mit Sicherheit auch kuerzer schreiben).
Durch die vielen Funktionsaufrufe ist der Code aber seeehhr langsam - Esskar's Variante duerfte um einiges schneller sein.

edit: perl-Tag hat Code manipuliert\n\n

<!--EDIT|coax|1112556828-->
,,Das perlt aber heute wieder...'' -- Dittsche

View full thread Verzeichnisbaum: Flaches Array mehrdimensional printen