Вложенная структура Perl: рекурсивная функция
Как продолжение моего предыдущего поста здесь!
Я проверил алгоритм с вложенными ссылками хеша:
Алгоритм:
use strict;
use warnings;
&expand_references2([a,b,{c=>123},d]);
sub expand_references2 {
my $indenting = -1;
my $inner; $inner = sub {
my $ref = $_[0];
my $key = $_[1];
$indenting++;
if(ref $ref eq 'ARRAY'){
print ' ' x $indenting;
printf("%s\n",($key) ? $key : '');
$inner->($_) for @{$ref};
}elsif(ref $ref eq 'HASH'){
print ' ' x $indenting;
printf("%s\n",($key) ? $key : '');
for my $k(sort keys %{$ref}){
$inner->($ref->{$k},$k);
}
}else{
if($key){
print ' ' x $indenting,$key,' => ',$ref,"\n";
}else{
print ' ' x $indenting,$ref,"\n";
}
}
$indenting--;
};
$inner->($_) for @_;
}
В некоторых случаях отступ и символ новой строки не отображаются должным образом:
Example1:
expand_references2(hash=>{
d1=>{a=>123,
b=>234},
d2=>[1,2,3],
d3=>'hello'});
Выход:
Hash
<newline> # not required
d1
a => 123
b => 234
d2
1
2
3
d3 => hello
Вместо этого я бы предпочел вывод что-то вроде этого:
Hash
d1
a => 123
b => 234
d2
1
2
3
d3 => hello
ИЛИ ЖЕ
Hash
d1
a => 123
b => 234
d2
1
2
3
d3 => hello
Example2:
expand_references2([a,b,{c=>123},d]);
выход:
a
b
c=>123 # indentation not required
d
Любое руководство о том, как достичь вышеизложенного в сценарии или сделать правильный отступ без лишних переносов строки?
Ценю любую помощь.
Спасибо
1 ответ
Я бы использовал несколько иной подход:
sub prindent {
my( $ref, $ind ) = @_;
if( ref( $ref ) eq 'HASH' ){
for my $key (sort keys %{$ref}){
print ' ' x $ind, $key;
my $val = $ref->{$key};
if( ref( $val ) ){
print "\n";
prindent( $val, $ind + 1 );
} else {
print " => $val\n";
}
}
} elsif( ref( $ref ) eq 'ARRAY' ){
for my $el ( @{$ref} ){
if( ref( $el ) ){
prindent( $el, $ind + 1 );
} else {
print ' ' x $ind, "$el\n";
}
}
}
}
sub prindent2 {
my( $key, $val ) = @_;
if( defined $val ){
print "$key\n";
prindent( $val, 1 );
} else {
prindent( $key, 0 );
}
}
Это производит:
hash
d1
a => 123
b => 234
d2
1
2
3
d3 => hello
a
b
c => 123
d
Вам может не понравиться вывод для многомерных массивов: все элементы находятся в одном столбце.