This has been tried (and done) many times before; it's almost a coming-of-age ritual. Heck, I've even done it myself before, long ago.
This is the way I feel like doing it today. What I don't like about it is that its performance is something like O(nm), where m is average number of parts in each path.
I'm sure there are better (for most definitions of "better") ways to do it; for example, tye suggested his Data::Diver module.
sub paths2tree { my $hr = {}; @{$hr}{@_} = map { {} } @_; my $n_repls; do { $n_repls=0; for ( sort { length($b) <=> length($a) } keys %$hr ) { if ( /(.*)\\(.*)/ ) { $hr->{$1}{$2} = delete $hr->{$_}; $n_repls++; } } } while ( $n_repls ); $hr }
NB - This is hardcoded for the CP/M-style backslash path separator. You could generalize it if you want to. ;-)
Update: Upon reflection, I'm not sure you can get away from the O(nm) performance. At best, you can make the inner loop more efficient, e.g. by eliminating an explicit for loop and using a //g regex instead. But that doesn't change the "big O".
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Parse a list of path strings into a nested hash
by GrandFather (Saint) on Sep 04, 2010 at 03:14 UTC | |
by Jim (Curate) on Sep 06, 2010 at 01:52 UTC | |
by GrandFather (Saint) on Sep 06, 2010 at 02:32 UTC | |
by repellent (Priest) on Sep 09, 2010 at 23:37 UTC | |
Re: Parse a list of path strings into a nested hash
by ambrus (Abbot) on Sep 06, 2010 at 14:09 UTC | |
by jdporter (Paladin) on Sep 06, 2010 at 19:05 UTC | |
by ambrus (Abbot) on Sep 06, 2010 at 20:53 UTC | |
by jdporter (Paladin) on Sep 07, 2010 at 14:32 UTC |