Я у себя использую такой велосипед
Код | sub traverse { my ($parent, $onEachSub) = @_; my (@stack, @parents, @keys); push @parents, $parent; push @keys, keys %$parent;
my $level = 0; while(1) { my $current_key = shift @keys; $parent = $parents[-1]; if (!$current_key) { my $arr_ref = pop @stack; if(!$arr_ref) { # stack is empty last; } @keys = @$arr_ref; $level--; $parent = pop @parents; next; } my $current = $parent->{$current_key}; # call handler &$onEachSub($current_key,$current,$level) if defined $onEachSub;
my @subnode_keys = $current ? keys %$current : (); if (@subnode_keys) { push @stack, [ @keys ]; push @parents, $current; $parent = $current; $level++; @keys = @subnode_keys; next; } } } |
Хэш допустим такой :
Код | my $HASH= { 'a' => { 'a0' => { 'a0_1' => { 'x'=>undef, 'y'=>undef }, }, 'a1' => undef, 'a2' => { 'a2_1' => undef, }, }, 'b' => { 'b1' => undef, 'b2' => { 'b2_1' => { 'M'=>undef, 'N'=>undef } }, 'b3' => { 'b3_1' => undef }, }
}; |
Вызываю так
Код | traverse($HASH, sub { # $current_key - ключ текущего элемента, # $current - сам текущий элемент (анонимный субхэш), # $level - уровень вложенности текущего элемента ("0" = верхний уровень) my ($current_key, $current, $level) = @_; print " "x$level, "$current_key\n"; });
|
результат

|