Perl嵌套结构:递归函数

时间:2016-03-25 01:54:59

标签: perl recursion recursive-datastructures nested-reference

作为我之前发布的帖子here的后续内容!

我使用嵌套哈希引用测试了算法:

算法:

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 @_;
}

在某些情况下,缩进和换行符不会按预期显示:

例1:

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

OR

Hash
  d1                                                                                                                                                                                                           
    a => 123                                                                                                                                                                                                   
    b => 234                                                                                                                                                                                                   

  d2                                                                                                                                                                                                           
    1                                                                                                                                                                                                          
    2                                                                                                                                                                                                          
    3                                                                                                                                                                                                          

  d3 => hello

例2:

expand_references2([a,b,{c=>123},d]);

输出:

a
b
  c=>123           # indentation not required
d

有关如何在没有额外换行符的情况下实现上述方案或缩进的任何指导?

感谢任何帮助。

由于

1 个答案:

答案 0 :(得分:0)

我使用了一种不同的方法:

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

您可能不喜欢多维数组的输出:所有元素都在一列中。