Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Multiple arrays in a hash

by gasho (Beadle)
on Jun 19, 2007 at 19:06 UTC ( #622077=perlquestion: print w/replies, xml ) Need Help??

gasho has asked for the wisdom of the Perl Monks concerning the following question:

Dear Perl Monks. I have collected bunch of arrays that first element of each array should be a key I would like to produce print out like bellow. Do you have more elegant solution ? I will appreciate
ArrA = qw(A 1 2 3 4 5); ArrB = qw(B 1 2 5 6); ArrC = qw(C 2 3); for ($i=1; $i < 6; $i++) { push(@{$CAPABILITIES{$ArrA[$i]}}, $ArrA[0]); push(@{$CAPABILITIES{$ArrB[$i]}}, $ArrB[0]); push(@{$CAPABILITIES{$ArrC[$i]}}, $ArrC[0]); } foreach $key (sort (keys %CAPABILITIES)) { print "$key => "; foreach $role (sort @{$CAPABILITIES{$key}}) { print "$role "; } print "\n"; } # Desired Printout =begin COMMENT Key/Value ====================== 1 => A B 2 => A B C 3 => A C 4 => A 5 => A B 6 => B OR Key/Value A B C ====================== 1 X X 2 X X X 3 X X 4 X 5 X X 6 X =end COMMENT =cut
(: Life is short enjoy it :)

Replies are listed 'Best First'.
Re: Multiple arrays in a hash
by ikegami (Patriarch) on Jun 19, 2007 at 19:34 UTC

    What you called "CABABILITIES", I called "roles" for short.
    That which has "CABABILITIES", I called "actor".

    Instead of building a hash of roles by actor, build a hash of actors by role. That way, your data structure will ressemble your output. (Update: Oops, that is what you are doing. The rest of the post applies, though.)

    In the code below, I replaced doing the same thing to three different arrays with a single loop.

    use strict; use warnings; my @arrays = ( [ qw( A 1 2 3 4 5 ) ], [ qw( B 1 2 5 6 ) ], [ qw( C 2 3 ) ], ); my %actors_by_role; foreach my $array (@arrays) { my ($actor, @roles) = @$array; foreach my $role (@roles) { push @{$actors_by_role{$role}}, $actor; } } my @roles = sort keys %actors_by_role; foreach my $role (@roles) { print(join("\t", $role => sort @{$actors_by_role{$role}}), "\n"); }

    Output:

    1 A B 2 A B C 3 A C 4 A 5 A B 6 B

    From there, it's not hard to get the second output.

    use strict; use warnings; my @arrays = ( [ qw( A 1 2 3 4 5 ) ], [ qw( B 1 2 5 6 ) ], [ qw( C 2 3 ) ], ); my %actors; my %actors_by_role; foreach my $array (@arrays) { my @roles = @$array; my $actor = shift(@roles); $actors{$actor} = 1; foreach my $role (@roles) { $actors_by_role{$role}{$actor} = 1; } } my @roles = sort keys %actors_by_role; my @actors = sort keys %actors; { foreach my $actor (@actors) { print("\t", $actor); } print("\n"); } foreach my $role (@roles) { print($role); foreach my $actor (@actors) { print("\t", $actors_by_role{$role}{$actor} ? 'X' : ' '); } print("\n"); }

    Output:

    A B C 1 X X 2 X X X 3 X X 4 X 5 X X 6 X
      I appreciate your help. Thanks , Gasho
      (: Life is short enjoy it :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://622077]
Approved by clinton
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2023-03-24 18:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Which type of climate do you prefer to live in?






    Results (61 votes). Check out past polls.

    Notices?