The following post presents three possible solutions, basically listed in the order in which they came to my mind. The second is probably my favorite, but they each are worth looking at.
Here's a little snippet that uses hashes for quick lookups within @p_types and @c_types. It uses these lookup tables to test the elements within @true and @false to see if they meet the criteria.
use strict;
use warnings;
my( @p_types ) = qw/ pam php kph /;
my( @c_types ) = qw/ cam c1 c2 /;
my @true = qw/ pam c2 /;
my @false = qw/ cam c2 /;
my %p_hash;
@p_hash{@p_types} = ();
my %c_hash;
@c_hash{@c_types} = ();
print "\@true is ",
( qualify( \@true, \%p_hash, \%c_hash ) )
? "True.\n"
: "False.\n";
print "\@false is ",
( qualify( \@false, \%p_hash, \%c_hash) )
? "True.\n"
: "False.\n";
sub qualify {
my( $test_aref, $p_href, $c_href ) = @_;
if(
grep{ exists $p_href->{$_} } @{$test_aref} and
grep{ exists $c_href->{$_} } @{$test_aref}
) {
return 1;
} else {
return 0;
}
}
I think this is what you're after. It would be neater to create an object where the constructor builds the two test hashes, and qualify() becomes an object method taking the target array as an argument. That would help to encapsulate and generalize the hashes, while still preserving them to be tested against various target arrays. I'll post an example in a bit.
Update:
And here's an example of an object oriented technique that generalizes the set hashes and encapsulates the test sets for repeated testing as long as their object stays in scope.
package All_In;
use strict;
use warnings;
sub new {
my $class = shift;
my( $p_types, $c_types ) = @_;
my( %p_hash, %c_hash );
@p_hash{ @{$p_types} } = ();
@c_hash{ @{$c_types} } = ();
my $self = {};
$self->{p_hash} = \%p_hash;
$self->{c_hash} = \%c_hash;
bless $self, $class;
}
sub qualify {
my( $self, @target ) = @_;
if(
grep{ exists $self->{p_hash}{$_} } @target
and grep{ exists $self->{c_hash}{$_} } @target
){
return 1;
} else {
return 0;
}
}
1;
package main;
use strict;
use warnings;
my $sets = All_In->new(
[ qw/ pam php kph / ],
[ qw/ cam c1 c2 / ]
);
my @true = qw/ pam c2 /;
my @false = qw/ cam c2 /;
print "\@true is ",
$sets->qualify( @true )
? "True.\n"
: "False.\n";
print "\@false is ",
$sets->qualify( @false )
? "True.\n"
: "False.\n";
Update 2:
And how could I pass on an opportunity to tinker with Quantum::Superpositions? The following solution is certanly much easier to follow, but bound to be the least efficient from a runtime standpoint. But its simplicity is very enticing:
use strict;
use warnings;
use Quantum::Superpositions;
my @p_types = qw/ pam php kph /;
my @c_types = qw/ cam c1 c2 /;
my @true = qw/ pam c2 /;
my @false = qw/ cam c2 /;
print "\@true is ",
qualify( \@true, \@p_types, \@c_types )
? "True.\n"
: "False.\n";
print "\@false is ",
qualify( \@false, \@p_types, \@c_types )
? "True.\n"
: "False.\n";
sub qualify {
my( $target, $p_types, $c_types ) = @_;
my $quantum_target = any( @{$target} );
return 1 if (
$quantum_target eq any( @{$p_types} )
and $quantum_target eq any( @{$c_types} )
);
return 0;
}
|