I'm walking a hash with the following code:
What I would like it to do is to create a series of path / value pairs along the lines:use 5.016; use Data::Walk; use Storable qw/dclone/; use Data::Dumper::Concise; my %h3 = ( a => [ { b => { c => [qw/d e/] } }, { f => { g => 'h' } }, ], ); my @found; my %paths; my @path; my $walker = sub { say qq{Visit depth $Data::Walk::depth, index $Data::Walk::index } +. (ref $_ ? '' : qq{"$_"}) . qq{ Seen: $Data::Walk::seen}; if ($Data::Walk::type eq 'HASH') { if ( !ref $_ && $Data::Walk::index % 2 == 0 ) { @path = () if $Data::Walk::depth == 2; push @path, $_; } elsif (@path) { my $key = join '.', @path; $paths{$key} = ref $_ ? dclone $_ : $_; } } elsif ($Data::Walk::type eq 'ARRAY') { my $key = join '.', @path, $Data::Walk::index; $paths{$key} = $_; pop @path if $Data::Walk::index == $#{$Data::Walk::container} +&& !ref $_; push @path, $Data::Walk::index if ref $_; } else { say qq{Something else here!} } 1; }; %paths = (); @path = (); walk $walker, \%h3; print Dumper \%paths;
my %paths = ( 'a.0.b.c.0' => d, 'a.0.b.c.1' => e, 'a.1.f.g' => h, );
Note that the intermediate paths, e.g. a.0 => ..., have been omitted for clarity.
What I can't figure out is how to know when I'm done with a particular hashref, and can safely pop the key off @path. What I've got right now works for cases where you have a hashref of (hashref of hashrefs) or a hashref of arrayrefs, but not the more complex case I have above.
In reply to Walking a hash using Data::Walk by PopeFelix
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |