perl中的grep函数无法识别“boolean”上下文,因为在Perl中根本没有“布尔”上下文。
所以,如果我做这样的事情
print "matched\n" if grep { print "$_\n"; $_&1 } 1..31
将打印从1到31的数字,而不是仅打印“1”,这足以在“if”中获得“true”结果。
为了避免这种行为,我必须做一些可怕的事情:
print "matched\n" if do { my $fl; $_&1 and $fl=1, last for 1..31; $fl }
也许可以用最简单的方式完成?是否有一些在CPAN上实现“布尔grep”的快速XS代码?
答案 0 :(得分:5)
每个人似乎都忘记了他们可以编写潜艇以隐藏“糟糕”的细节。
sub any(&@) { my $cb = shift; for (@_) { return 1 if $cb->() } 0 }
say "match" if any { say; $_ & 1 } 1..31;
尽管如此,any
已由List::Util提供。 (另请查看List::MoreUtils。)
请注意,在调用any
之前,迭代的项目列表仍将完全放在堆栈上。与不必要多次调用sub相比,这相当便宜,但它仍然可能是一个问题。我认为这是List::Gen试图解决的问题。
答案 1 :(得分:0)
这听起来像是寻找工作的工具而不是寻找工具的工作。如果任务是通过一个数字列表并在找到符合条件的数字时停止,请不要使用设计想要检查每个元素的内容:
cache-control
答案 2 :(得分:0)
grep能够作弊;它执行的块实际上并不是一个子程序,并且能够以比它更快的速度运行它,并且非grep替代方案被卡住进行子调用。
IMO,除非你有一个很长的列表并且很可能在开始时找到所需的匹配,所以没有理由不使用grep。或者至少,让你的代码更具可读性的原因(使用"任何"或者这样做)可以超过任何性能增益(或损失)。