SPUG: Pretty-Printing Nested Hashes?

Ryan Allen ryan at the-summit.net
Mon Sep 19 15:48:03 PDT 2005


Sorry, that does not exactly answer your question.  Should of read the
whole E-mail first.

- Ryan
(who just learned about Data::Dumper and wants to tell the world about
 it)


* Michael Wallendahl <mwallend at spikus.com> wrote on [09-19-05y 15:40]:
> Hello,
> 
> I'm wondering if anyone has a suggestions on a good algorithm to
> 'pretty-print' a nested hash in tabular form?
> 
> Take the following hash:
> 
> ---BEGIN PERL---
> 
> #!perl
> 
> use strict;
> use warnings;
> 
> my %h;
> 
> $h{one}->{First} = 'Bob';
> $h{one}->{Last}  = 'Marley';
> $h{two}->{First} = 'Sue Ellen';
> $h{two}->{Last}  = 'Smith';
> 
> ---END PERL---
> 
> Is there an easy way to print out the contents of %h in a tabular form
> so that the width of each column is set to the largest element?   Like
> this:
> 
>     First     Last 
>     --------- ------
>     Bob       Marley
>     Sue Ellen Smith
> 
> In the past I've resorted to traversing the nested hash looking at each
> element's value, saving the largest width away in a variable, and then
> using printf statements. This quickly gets messy as the number of columns
> increase.
> 
> For example, continuing on with perl:
> 
> ---BEGIN PERL---
> 
> my $max_first = 5; # Length of column name 'First' as the min.
> my $max_last  = 4; # Length of column name 'Last' as the min.
> foreach my $user (keys %h) {
>    my $len_f = length($h{$user}->{First});
>    my $len_l = length($h{$user}->{Last });
>    if ($len_f > $max_first) { $max_first = $len_f; }
>    if ($len_l > $max_last ) { $max_last  = $len_l; }
> }
> 
> print "Max length of First column: $max_first\n";
> print "Max length of Last column : $max_last\n";
> 
> # print heading.
> printf "%-*s %-*s\n",
>     $max_first, 'First',
>     $max_last , 'Last';
> 
> # print underlines for heading.
> printf "%-*s %-*s\n",
>     $max_first, '-' x $max_first,
>     $max_last , '-' x $max_last;
> 
> # print out data.
> foreach my $user (keys %h) {
>     printf "%-*s %-*s\n",
>         $max_first, $h{$user}->{First},
>         $max_last , $h{$user}->{Last },
> 
> }
> 
> ---END PERL---
> 
> Is there an easier way to do this that I'm just overlooking?
> All those printf's just look messy to me.
> 
> Thanks,
> -Mike
> 
> 
> _____________________________________________________________
> Seattle Perl Users Group Mailing List  
>      POST TO: spug-list at pm.org
> SUBSCRIPTION: http://mail.pm.org/mailman/listinfo/spug-list
>     MEETINGS: 3rd Tuesdays, Location: Amazon.com Pac-Med
>     WEB PAGE: http://seattleperl.org/
> 

-- 

+-----------------------------+
|     ryan at the-summit.net     |
|  http://www.the-summit.net  |
+-----------------------------+


More information about the spug-list mailing list