2016-03-25 20 views
-1

Als Folge zu meinem früheren Beitrag here!Perl verschachtelte Struktur: rekursive Funktion

testete ich den Algorithmus mit verschachtelten Hashreferenzen:

Algorithmus:

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

In einigen Fällen die Vertiefung und das Newline-Zeichen nicht wie erwartet angezeigt werden:

Example1:

expand_references2(hash=>{ 
          d1=>{a=>123, 
           b=>234}, 
          d2=>[1,2,3], 
          d3=>'hello'}); 

Ausgabe:

Hash 
<newline>     # not required                                                    
    d1                                                   
    a => 123                                                 
    b => 234                                                 
    d2                                                   
    1                                                   
    2                                                   
    3                                                   
    d3 => hello 

Stattdessen würde ich eine Ausgabe in etwa so bevorzugen:

Hash 
    d1                                                   
    a => 123                                                 
    b => 234                                                 
    d2                                                   
    1                                                   
    2                                                   
    3                                                   
    d3 => hello 

ODER

Hash 
    d1                                                   
    a => 123                                                 
    b => 234                                                 

    d2                                                   
    1                                                   
    2                                                   
    3                                                   

    d3 => hello 

Example2:

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

Ausgabe:

a 
b 
    c=>123   # indentation not required 
d 

Gibt es eine Anleitung, wie Sie das obige Szenario erreichen oder es ohne zusätzliche Zeilenumbrüche einrücken können?

Schätzen Sie jede Hilfe.

Dank

Antwort

0

ich einen etwas anderen Ansatz verwenden würde:

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); 
    } 
} 

Dies erzeugt:

hash 
    d1 
    a => 123 
    b => 234 
    d2 
    1 
    2 
    3 
    d3 => hello 

a 
b 
    c => 123 
d 

Sie können nicht wie die Ausgabe für mehrdimensionale Arrays: Alle Elemente sind in einem Säule.