I have array @hon_data
. If any elements of the array are one of a known list of values, I return zero.
for my $hon_field (@hon_data) {
if($hon_field ne 'B' and $hon_field ne 'S' and $hon_field ne 'G' and
$hon_field ne 'D' and $hon_field ne 'L') {
return 0;
}
}
The number of values to check is growing, so this approach is getting complicated to manage. Is there a way to do this with the values in an array?
my @results =("B","G","S","D","N","L");
my @results2 = ("A","G","S","D","N","L");
sub uniq {
my %seen;
grep { !$seen{$_} } @_;
}
my @unique = uniq(@results, @results2);
In result2 A is unique value and it should return A only But this code is not working.
CodePudding user response:
You're asking how to replace the hardcoded loop with a dynamic one. The following is one way this could be done:
for my $hon_field ( @hon_data ) {
for my $ok (qw( B S G D L )) {
if ( $hon_field ne $ok ) {
return 0;
}
}
}
That is a lot better. But if the elements are strings, the inner loop can be replaced with a hash lookup.
my %ok = map { $_ => 1 } qw( B S G D L );
for my $hon_field ( @hon_data ) {
if ( !$ok{ $hon_field } ) {
return 0;
}
}
This can also be written as follows:
use List::Util qw( any );
my %ok = map { $_ => 1 } qw( B S G D L );
return 0 if any { !$ok{$_} } @hon_data;
A similar approach can be used to find the difference of sets.
my %ok = map { $_ => 1 } qw( B S G D L );;
my @diff = grep { !$ok{ $_ } } @hon_data; # diff = hon_data - { B, S, G, D, L }