my @rows = ({id=>0,fur=>'t',legs=>'2',tail=>'y'}, {id=>1,fur=>'t',legs=>'2',tail=>'y'}, {id=>2,fur=>'t',legs=>'2',tail=>'y'}, {id=>3,fur=>'f',legs=>'4',tail=>'y'}, {id=>4,fur=>'f',legs=>'4',tail=>'y'}, ); my %lookup_id = map { $_->{id}, $_ } @rows; my %lookup_fur_and_legs; while (my ($id,$ref) = each %lookup_id) { my $key = $ref->{fur} . $ref->{legs}; if (exists $lookup_fur_and_legs{$key}) { push @{$lookup_fur_and_legs{$key}}, $ref; } else { $lookup_fur_and_legs{$key} = [$ref]; } }