我有一个包含以下值的数组:
push @fruitArray, "apple|0";
push @fruitArray, "apple|1";
push @fruitArray, "pear|0";
push @fruitArray, "pear|0";
我想知道这个数组中是否存在字符串“apple”(忽略“| 0”“| 1”)
我正在使用:
$fruit = 'apple';
if( $fruit ~~ @fruitArray ){ print "I found apple"; }
哪个不起作用。
答案 0 :(得分:5)
不要使用智能匹配。它由于多种原因从未正常工作,现在标记为 experimental
在这种情况下,您可以使用grep
代替相应的正则表达式
此程序会测试@fruitArray
的每个元素,以查看它是否以$fruit
中的字母开头,后跟管道符|
。 grep
返回与模式匹配的元素数,如果至少有一个匹配
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
答案 1 :(得分:1)
我 - 就像 @Borodin 一样 - 只会使用grep()
:
$fruit = 'apple';
if (grep(/^\Q$fruit\E\|/, @fruitArray)) { print "I found apple"; }
输出:
I found apple
\Q...\E
将您的字符串转换为正则表达式模式。|
会阻止查找名称以您正在寻找的水果名称开头的水果。简单有效......: - )
更新:从数组中删除元素:
$fruit = 'apple';
@fruitsArrayWithoutApples = grep ! /^\Q$fruit\E|/, @fruitArray;
答案 2 :(得分:1)
如果你的Perl不是很古老,你可以使用first
模块中的List::Util
子程序(它成为Perl 5.8的核心模块)来有效地进行检查:
use List::Util qw{ first };
my $first_fruit = first { /\Q$fruit\E/ } @fruitArray;
if ( defined $first_fruit ) { print "I found $fruit\n"; }
答案 3 :(得分:0)
不要使用grep
来循环整个数组,即使它在第一个索引中找到了你要查找的内容,所以效率很低。
如果找到子串'apple',则返回true,然后返回并且不完成迭代遍历数组的其余部分
#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;
}
}
}
答案 4 :(得分:0)
您可以使用smartmatch sun without melting your wings:
接近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 ;
如果中缀match()
读得不好,还有一个[M]
函数。
我喜欢match::simple
几乎我对~~
所期望的一切的方式,而没有任何惊人的复杂性。如果你能熟练掌握perl,那么你可能认为这不是必要的东西,但是 - 尤其是match()
- 代码可以令人愉快地阅读......代价是强制使用引用,< EM>等