Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > manipulating a hash of hashes

Reply
Thread Tools

manipulating a hash of hashes

 
 
Aaron DeLoach
Guest
Posts: n/a
 
      07-07-2004
Hi all,

I have the following HoH:

my %payment_methods =
(
"Credit Cards"=>{
"ae" => "American Express",
"di" => "Discover",
"vi" => "Visa",
"jc" => "JCB",
"dc" => "Diners Club",
"mc" => "MasterCard",
},
"Other"=>{
"mo" => "Money Order",
"po" => "Purchase Order",
},
"Checks"=>{
"pe" => "Personal Check",
"co" => "Company Check",
"ca" => "Cashiers Check",
"ce" => "Certified Check",
},
);

I would like to construct an html table of the data as follows. I don't need
help with the html, just the ability to produce the data in column/row
format.

(hash names)
row1 Credit Cards | Other | Check
(now values)
row2 American express | Money Order | Company Check
row3 Discover | Purchase Order | Cashiers Check
row4 Visa | | Certified Check
row5 JCB | |
row6 Diners Club | |

and so on...

As you can see from the example data ends in different columns as the hash
runs out of values. Any assistance would be greatly appreciated.

Regards
Aaron




 
Reply With Quote
 
 
 
 
Paul Lalli
Guest
Posts: n/a
 
      07-07-2004
On Wed, 7 Jul 2004, Aaron DeLoach wrote:

> Hi all,
>
> I have the following HoH:
>
> my %payment_methods =
> (
> "Credit Cards"=>{
> "ae" => "American Express",
> "di" => "Discover",
> "vi" => "Visa",
> "jc" => "JCB",
> "dc" => "Diners Club",
> "mc" => "MasterCard",
> },
> "Other"=>{
> "mo" => "Money Order",
> "po" => "Purchase Order",
> },
> "Checks"=>{
> "pe" => "Personal Check",
> "co" => "Company Check",
> "ca" => "Cashiers Check",
> "ce" => "Certified Check",
> },
> );
>
> I would like to construct an html table of the data as follows. I don't need
> help with the html, just the ability to produce the data in column/row
> format.
>
> (hash names)
> row1 Credit Cards | Other | Check
> (now values)
> row2 American express | Money Order | Company Check
> row3 Discover | Purchase Order | Cashiers Check
> row4 Visa | | Certified Check
> row5 JCB | |
> row6 Diners Club | |
>
> and so on...
>
> As you can see from the example data ends in different columns as the hash
> runs out of values. Any assistance would be greatly appreciated.



Don't try to do what's already been done before. Use a module that's
already written, like HTML::Table, available on CPAN:

#!/usr/bin/perl
use strict;
use warnings;
use HTML::Table
my %payment_methods =
(
"Credit Cards"=>{
"ae" => "American Express",
"di" => "Discover",
"vi" => "Visa",
"jc" => "JCB",
"dc" => "Diners Club",
"mc" => "MasterCard",
},
"Other"=>{
"mo" => "Money Order",
"po" => "Purchase Order",
},
"Checks"=>{
"pe" => "Personal Check",
"co" => "Company Check",
"ca" => "Cashiers Check",
"ce" => "Certified Check",
},
);

my $table = new HTML::Table;
foreach $type (keys %payment_methods) {
$table->addCol($type, values(%{$payment_methods{$type}}));
}

print $table->getTable, "\n";

__END__

(note that formatting, for example the column headings, is left as an
excercise to the reader. It should be possible once you've read the
documentation for HTML::Table)

Paul Lalli
 
Reply With Quote
 
 
 
 
Jeff 'japhy' Pinyan
Guest
Posts: n/a
 
      07-07-2004
[posted & mailed]

On Wed, 7 Jul 2004, Aaron DeLoach wrote:

[reformatted]
>Credit | Other | Check
>===========================================
>AmEx | Money Order | Company Check
>Disc | Purchase Order | Cashiers Check
>Visa | | Certified Check
>JCB | | Personal Check
>Diner | |


>As you can see from the example data ends in different columns as the hash
>runs out of values. Any assistance would be greatly appreciated.


I would first get the data out of the hashrefs:

my @data = map [values %$_], values %payment_methods;

This gets us from:

my %payment_methods = (
"Credit Cards" => {
"ae" => "American Express",
"di" => "Discover",
"vi" => "Visa",
"jc" => "JCB",
"dc" => "Diners Club",
"mc" => "MasterCard",
},
"Other"=>{
"mo" => "Money Order",
"po" => "Purchase Order",
},
"Checks"=>{
"pe" => "Personal Check",
"co" => "Company Check",
"ca" => "Cashiers Check",
"ce" => "Certified Check",
},
);

to this:

@data = (
[ "American Express", "Discover", "Visa", ... ],
[ "Money Order", "Purchase Order" ],
[ "Personal Check", "Company Check", ... ],
);

though not necessarily in those orders. Now we need to know the dimension
of the largest hashref (now arrayref):

my $max = 0;
for (@data) { $max = @$_ if $max < @$_ }

Now we can do this in a naive manner or a more cunning manner:

print "<table>\n";
for my $i (0 .. $max-1) {
print "<tr>\n";
for (@data) {
print "<td>$_->[$i]</td>";
}
print "\n</tr>\n";
}
print "</table>\n";

That's naive, because you'll be getting empty cells whenever an arrayref
"runs out" of elements. The more cunning way is to insert "rowspan"
attributes when an array is on its last element, and then to skip that
array afterwards.

print "<table>\n";
for my $i (0 .. $max-1) {
print "<tr>\n";
for (@data) {
# skip if we're past the end
next if $#$_ < $i;

# if this is the last element, make its rowspan bigger
my $span = ($#$_ == $i) ? $max - $#$_ : 1;

print "<td rowspan=$span valign='top'>$_->[$i]</td>";
}
print "\n</tr>\n";
}
print "</table>\n";

--
Jeff "japhy" Pinyan % How can we ever be the sold short or
RPI Acacia Brother #734 % the cheated, we who for every service
RPI Corporation Secretary % have long ago been overpaid?
http://japhy.perlmonk.org/ %
http://www.perlmonks.org/ % -- Meister Eckhart



 
Reply With Quote
 
Brad Baxter
Guest
Posts: n/a
 
      07-07-2004
On Wed, 7 Jul 2004, Aaron DeLoach wrote:

> Hi all,
>
> I have the following HoH:
>
> my %payment_methods =
> (
> "Credit Cards"=>{
> "ae" => "American Express",
> "di" => "Discover",
> "vi" => "Visa",
> "jc" => "JCB",
> "dc" => "Diners Club",
> "mc" => "MasterCard",
> },
> "Other"=>{
> "mo" => "Money Order",
> "po" => "Purchase Order",
> },
> "Checks"=>{
> "pe" => "Personal Check",
> "co" => "Company Check",
> "ca" => "Cashiers Check",
> "ce" => "Certified Check",
> },
> );
>
> I would like to construct an html table of the data as follows. I don't need
> help with the html, just the ability to produce the data in column/row
> format.
>
> (hash names)
> row1 Credit Cards | Other | Check
> (now values)
> row2 American express | Money Order | Company Check
> row3 Discover | Purchase Order | Cashiers Check
> row4 Visa | | Certified Check
> row5 JCB | |
> row6 Diners Club | |
>
> and so on...
>
> As you can see from the example data ends in different columns as the hash
> runs out of values. Any assistance would be greatly appreciated.
>
> Regards
> Aaron


Below is another solution using a module. I cheated and used 'sort' in a
couple of places. If you really want the order you show above, then
replace sort with a different method.


use Array::Each;

my @headings = sort keys %payment_methods;

my $set = Array::Each->new(
set => [ map [sort values %$_],
@payment_methods{ @headings }, ],
undef => '&nbsp;',
bound => 0,
count => 1,
);

print
"<table border='1'>\n",
"<tr> <td></td>",
map( "<th>$_</th> ", @headings ),
"</tr>\n";
while( my @row = $set->each ) {
printf "<tr> <td>row%d.</td> ", pop @row;
print map( "<td>$_</td> ", @row ), "</tr>\n";
}
print "</table>\n";



Regards,

Brad

--
http://search.cpan.org/~bbaxter/Array-Each-0.02/Each.pm
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
"Pseudo-hashes are deprecated" error and accessing a hash of hashes ernestm@mindspring.com Perl Misc 3 01-31-2006 04:40 AM
Hash of hashes, of hashes, of arrays of hashes Tim O'Donovan Perl Misc 5 10-28-2005 05:59 AM
Hashes of hashes or just one hash ? Perl Learner Perl Misc 11 06-09-2005 06:55 AM
Performance Improvement of complex data structure (hash of hashes of hashes) Scott Gilpin Perl Misc 2 08-26-2004 01:02 AM



Advertisments