I'm a perl newbie. I have a code in which a variable is loaded with several values during a foreach loop. What I want to do is to perform some operation on that variable only if its in that array. What is the most efficient way to do this in perl as the data I am working on is very large.
A simple example of my question is, say I have an array of fruits I want
@fruits_i_like = qw (mango banana apple);
But I have a $fruit variable in a foreach loop which gets the name of fruits from a data file that has all different types of fruits. How would I pick only those cases of $fruit that are in my @fruits_i_like array?
The exists() function in Perl is used to check whether an element in an given array or hash exists or not. This function returns 1 if the desired element is present in the given array or hash else returns 0.
The Perl grep() function is a filter that runs a regular expression on each element of an array and returns only the elements that evaluate as true. Using regular expressions can be extremely powerful and complex. The grep() functions uses the syntax @List = grep(Expression, @array).
Just as with the =~ regex match operator, the left side is the "subject" of the match, and the right side is the "pattern" to match against -- whether that be a plain scalar, a regex, an array or hash reference, a code reference, or whatever.
Perl access array elements Array elements are access by their indexes. The first index has value 0. The last index is $#vals . Array elements can be accessed from the end by using negative indexes.
Perl 5.10 or higher?
use strict;
use warnings;
use 5.10.0;
my @fruits_i_like = qw/mango banana apple/;
my $this_fruit = 'banana';
if ( $this_fruit ~~ \@fruits_i_like ) {
say "yummy, I like $this_fruit!";
}
Before 5.10:
use strict;
use warnings;
my @fruits_i_like = qw/mango banana apple/;
my $this_fruit = 'banana';
if ( scalar grep $this_fruit eq $_, @fruits_i_like ) {
print "yummy, I like $this_fruit!\n";
}
The downside is that the whole array is parsed through to find matches. This may not be the best option, in which case you can use List::MoreUtils
' any()
, which returns true once it matches a value and doesn't continue going through the array.
use strict;
use warnings;
use List::MoreUtils qw/any/;
my @fruits_i_like = qw/mango banana apple/;
my $this_fruit = 'banana';
if ( any { $this_fruit eq $_ } @fruits_i_like ) {
print "yummy, I like $this_fruit!\n";
}
Happy hacking!
You can use a hash like this :
my %h = map {$_ => 1 } @fruits_i_like;
if (exists $h{$this_fruit}) {
# do stuff
}
Here is a benchmark that compare this way vs mfontani solution
#!/usr/bin/perl
use warnings;
use strict;
use Benchmark qw(:all);
my @fruits_i_like = qw/mango banana apple/;
my $this_fruit = 'banana';
my %h = map {$_ => 1 } @fruits_i_like;
my $count = -3;
my $r = cmpthese($count, {
'grep' => sub {
if ( scalar grep $this_fruit eq $_, @fruits_i_like ) {
# do stuff
}
},
'hash' => sub {
if (exists $h{$this_fruit}) {
# do stuff
}
},
});
Output:
Rate grep hash
grep 1074911/s -- -76%
hash 4392945/s 309% --
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With