http://qs1969.pair.com?node_id=622086


in reply to Multiple arrays in a hash

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