Reputation: 560
I have an array with the following values:
push @fruitArray, "apple|0";
push @fruitArray, "apple|1";
push @fruitArray, "pear|0";
push @fruitArray, "pear|0";
I want to find out if the string "apple" exists in this array (ignoring the "|0" "|1")
I am using:
$fruit = 'apple';
if( $fruit ~~ @fruitArray ){ print "I found apple"; }
Which isn't working.
Upvotes: 4
Views: 1363
Reputation: 6378
You can get close to the smartmatch sun without melting your wings by using match::simple
:
use match::simple;
my @fruits = qw/apple|0 apple|1 pear|0 pear|0/;
$fruit = qr/apple/ ;
say "found $fruit" if $fruit |M| \@fruits ;
There's also a match()
function if the infix [M]
doesn't read well.
I like the way match::simple
does almost everything I expected from ~~
without any surprising complexity. If you're fluent in perl it probably isn't something you'd see as necessary, but - especially with match()
- code can be made pleasantly readable ... at the cost of imposing the use of references, etc.
Upvotes: 1
Reputation: 8054
If your Perl is not ancient, you can use the first
subroutine from the List::Util
module (which became a core module at Perl 5.8) to do the check efficiently:
use List::Util qw{ first };
my $first_fruit = first { /\Q$fruit\E/ } @fruitArray;
if ( defined $first_fruit ) { print "I found $fruit\n"; }
Upvotes: 1
Reputation: 1557
Don't use grep
, that will loop the entire array, even if it finds what you are looking for in the first index, so it is inefficient.
this will return true if it finds the substring 'apple', then return and not finish iterating through the rest of the array
#takes a reference to the array as the first parameter
sub find_apple{
@array_input = @{$_[0]};
foreach $fruit (@array_input){
if (index($fruit, 'apple') != -1){
return 1;
}
}
}
Upvotes: 0
Reputation: 17711
I - like @Borodin suggests, too - would simply use grep()
:
$fruit = 'apple';
if (grep(/^\Q$fruit\E\|/, @fruitArray)) { print "I found apple"; }
which outputs:
I found apple
\Q...\E
converts your string into a regex pattern.|
prevents finding a fruit whose name starts with the name of the fruit for which you are looking.Simple and effective... :-)
Update: to remove elements from array:
$fruit = 'apple';
@fruitsArrayWithoutApples = grep ! /^\Q$fruit\E|/, @fruitArray;
Upvotes: 1
Reputation: 126722
Don't use smart matching. It never worked properly for a number of reasons and it is now marked as experimental
In this case you can use grep
instead, together with an appropriate regex pattern
This program tests every element of @fruitArray
to see if it starts with the letters in $fruit
followed by a pipe character |
. grep
returns the number of elements that matched the pattern, which is a true value if at least one matched
my @fruitArray = qw/ apple|0 apple|1 pear|0 pear|0 /;
my $fruit = 'apple';
print "I found $fruit\n" if grep /^$fruit\|/, @fruitArray;
I found apple
Upvotes: 5