Mit*_*ldu 6 perl functional-programming
最近我一直在思考函数式编程.Perl提供了相当多的工具,但是有些东西我还没有找到.
Prototype具有枚举器的函数检测功能,描述就是这样:
Enumerator.detect(iterator[, context]) -> firstElement | undefined
Finds the first element for which the iterator returns true.
Run Code Online (Sandbox Code Playgroud)
在这种情况下,枚举器是任何列表,而迭代器是对函数的引用,该函数依次应用于列表的每个元素.
我期待这样的事情在的情况下申请在性能是重要的,即在遇到比赛停止时无视列表的其余部分节省了时间.
我也在寻找一种不涉及加载任何额外模块的解决方案,所以如果可能的话,应该只使用内置模块.如果可能的话,它应该像这样简洁:
my @result = map function @array;
Run Code Online (Sandbox Code Playgroud)
cjm*_*cjm 15
你说你不想要一个模块,但是这也正是first
在功能列表::的Util一样.这是一个核心模块,所以应该随处可用.
use List::Util qw(first);
my $first = first { some condition } @array;
Run Code Online (Sandbox Code Playgroud)
如果您坚持不使用模块,则可以将实现复制出List :: Util.如果有人知道更快的方法,它会在那里.(请注意,List :: Util包含一个XS实现,因此可能比任何纯Perl方法更快.它first
在List :: Util :: PP中也有一个纯Perl版本.)
请注意,正在测试的值将传递给子例程,$_
而不是作为参数传递.当您使用first { some condition} @values
表单时,这是一种方便,但如果您使用的是常规子例程,则需要记住这些内容.更多例子:
use 5.010; # I want to use 'say'; nothing else here is 5.10 specific
use List::Util qw(first);
say first { $_ > 3 } 1 .. 10; # prints 4
sub wanted { $_ > 4 }; # note we're using $_ not $_[0]
say first \&wanted, 1 .. 10; # prints 5
my $want = \&wanted; # Get a subroutine reference
say first \&$want, 1 .. 10; # This is how you pass a reference in a scalar
# someFunc expects a parameter instead of looking at $_
say first { someFunc($_) } 1 .. 10;
Run Code Online (Sandbox Code Playgroud)
未经测试,因为我在这台机器上没有Perl,但是:
sub first(\&@) {
my $pred = shift;
die "First argument to "first" must be a sub" unless ref $pred eq 'CODE';
for my $val (@_) {
return $val if $pred->($val);
}
return undef;
}
Run Code Online (Sandbox Code Playgroud)
然后用它作为:
my $first = first { sub performing test } @list;
Run Code Online (Sandbox Code Playgroud)
请注意,这并不区分列表中没有匹配项,列表中的一个元素是未定义的值并且具有该匹配项.
归档时间: |
|
查看次数: |
110 次 |
最近记录: |