-1

As a follow up to my previous post here!

I tested the algorithm with nested hash references:

Algorithm:

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 some cases, the indentation and the newline character do not display as expected:

Example1:

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

Output:

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

Instead I would prefer an output something like this:

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

Example2:

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

output:

a
b
  c=>123           # indentation not required
d

Any guidance on how to achieve the above to scenario or indenting it right without extra newlines?

Appreciate any help.

Thanks

Community
  • 1
  • 1
user2461335
  • 53
  • 1
  • 7

1 Answers1

0

I'd use a somewhat different approach:

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

This produces:

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

a
b
  c => 123
d

You may not like the output for multidimensional arrays: all elements are in one column.

laune
  • 30,276
  • 3
  • 26
  • 40