Reputation: 460
I've never really worked with Perl before (avoided it where I could) and so my knowledge is sparse on the topic.
I know the script I am looking at has an array of ProductID values in @::s_Ship_sShipProducts.
I was attempting to see if any of the ProductIDs in the array began with either B or S and execute a function if so, else do another function. But what I ended up with was for each ProductID do the statement. This is what I (admittedly salvaged) had.
my $i;
for $i (0 .. $#::s_Ship_sShipProducts) # for each product
if ($::s_Ship_sShipProducts[$i] =~ /^(B|S)/) # Determine if B or S product
{
if (defined $phashBandDefinition->{'FreeOver'} && CalculatePrice() > 250)
{$nCost = 0;}
}
else {
if (defined $phashBandDefinition->{'FreeOver'} && CalculatePrice() > $phashBandDefinition->{'FreeOver'})
{$nCost = 0;}
}
How could I change this so that the array was inspected to see if any ProductID was true and return true, or false if nothing matched? Then execute the appropriate function based on true or false? I have done some reading, but am still in the dark. Thanks for your time.
Upvotes: 1
Views: 145
Reputation: 129403
If the array is not too big (or you don't care THAT much about performance), you can check if there are any matching values via grep
:
if (my @matching_elements = grep { /^(B|S)/ } @::s_Ship_sShipProducts) {
# Better yet use /^[BS]/ expression - more idiomatic/readable
print "Found B/S\n";
} else {
print "NOT Found B/S\n";
}
When done, @matching_elements
would contain a list of matching IDs.
In the rare case when the array IS too big to scan through entirely and you only need to find the first occurance, you can use any of the array search optimization strategies discussed in binary search in an array in Perl
By the way, your approach to search works perfectly fine, you merely need to quit the loop once you found - and to boot, is one of those optimized approaches shown in the list above:
for my $i (0 .. $#::s_Ship_sShipProducts) # for each product
if ($::s_Ship_sShipProducts[$i] =~ /^[BS]/) { # Determine if B or S product
# Execute your logic here
last; # Found, get out of the loop.
}
}
NOTE: In Perl 5.10 and above, you can - instead of grep
- use a so-called "smart match" operator ~~
:
if (@::s_Ship_sShipProducts ~~ /^(B|S)/) {
# Your logic
}
Upvotes: 6