update: After writing the following, I realized you don't want multiple keys, you want one key incorporating multiple values. markkawika and bichonfrise74 have already shown you how to combine the values to create a composite key. You may incorporate that idea with the hash of lists below to deal with duplicate keys.
You can create as many hashes as you want, so multiple keys to the same data is not a problem. You can also create a hash of arrays, where each hash value is a reference to an array, allowing you to store multiple values for each key. This might address your issue with collisions. Whatever combination of first, middle and last name you use for keys, you will have the possibility of collisions, so a hash of arrays is probably the way to go. The following demonstrates one way of doing it.
use strict;
use warnings;
my ( %individuals_by_first_name, %individuals_by_middle_name);
foreach my $line (<DATA>) {
chomp($line);
my ($first, $middle, $last, $age, $sex, $location) = split(/,/, $l
+ine);
my $record = [ $first, $middle, $last, $age, $sex, $location ];
push(@{$individuals_by_first_name{$first}}, $record);
push(@{$individuals_by_middle_name{$middle}}, $record);
}
foreach my $first (sort keys %individuals_by_first_name) {
foreach my $individual (@{$individuals_by_first_name{$first}}) {
my ($first, $middle, $last, $age, $sex, $location) = @$individ
+ual;
print "$first: $middle, $last, $age, $sex, $location\n";
}
}
__DATA__
first1,middle1,last1,27,M,here
first2,middle2,last2,56,M,there
first3,middle3,last3,30,F,everywhere
first1,middle4,last4,7,F,home
first4,middle2,last3,22,M,away
which produces
first1: middle1, last1, 27, M, here
first1: middle4, last4, 7, F, home
first2: middle2, last2, 56, M, there
first3: middle3, last3, 30, F, everywhere
first4: middle2, last3, 22, M, away
or, by adding one more layer of hash, creating a hash of hashes of arrays,
you can add flexibility to add additional keys without adding variables and merge the two hashes into one.
use strict;
use warnings;
my %individuals;
foreach my $line (<DATA>) {
chomp($line);
my ($first, $middle, $last, $age, $sex, $location) = split(/,/, $l
+ine);
my $record = [ $first, $middle, $last, $age, $sex, $location ];
push(@{$individuals{first}{$first}}, $record);
push(@{$individuals{middle}{$middle}}, $record);
}
foreach my $first (sort keys %{$individuals{first}} ) {
foreach my $individual (@{$individuals{first}{$first}}) {
my ($first, $middle, $last, $age, $sex, $location) = @$individ
+ual;
print "$first: $middle, $last, $age, $sex, $location\n";
}
}
__DATA__
first1,middle1,last1,27,M,here
first2,middle2,last2,56,M,there
first3,middle3,last3,30,F,everywhere
first1,middle4,last4,7,F,home
first4,middle2,last3,22,M,away
This produces the same output as the first example. You can read more about references and data structures in perlref, perldsc, perllol and References. |