mapPerl中的函数是用Perl编写的吗?我只是无法弄清楚如何实现它.这是我的尝试:
use Data::Dumper;
sub Map {
my ($function, $sequence) = @_;
my @result;
foreach my $item (@$sequence) {
my $_ = $item;
push @result, $function->($item);
}
return @result
}
my @sample = qw(1 2 3 4 5);
print Dumper Map(sub { $_ * $_ }, \@sample);
print Dumper map({ $_ * $_ } @sample);
Run Code Online (Sandbox Code Playgroud)
$_in $function是未定义的,但是如何map克服这个?
Leo*_*ans 10
map 有一些特殊的语法,所以你不能在pure-perl中完全实现它,但这会非常接近它(只要你使用map的块形式):
sub Map(&@) {
my ($function, @sequence) = @_;
my @result;
foreach my $item (@sequence) {
local $_ = $item;
push @result, $function->($item);
}
return @result
}
use Data::Dumper;
my @sample = qw(1 2 3 4 5);
print Dumper Map { $_ * $_ } @sample;
print Dumper map { $_ * $_ } @sample;
Run Code Online (Sandbox Code Playgroud)
$_通过使用local $_而不是来克服未定义my $_.实际上你几乎从不想使用my $_(即使你确实想在几乎所有其他变量上使用它).
添加(&@)原型允许您不要sub在块前面指定.同样,你几乎从不想使用原型,但这是对它们的有效使用.
虽然接受的答案实现了类似map函数,但它不会像perl那样执行.的一个重要组成部分for,foreach,map,和grep是,$_他们提供给你的是永远的别名在参数列表中的值.这意味着调用s/a/b/任何这些结构中的内容将修改它们被调用的元素.这允许你写下这样的东西:
my ($x, $y) = qw(foo bar);
$_ .= '!' for $x, $y;
say "$x $y"; # foo! bar!
map {s/$/!!!/} $x, $y;
say "$x $y"; # foo!!!! bar!!!!
Run Code Online (Sandbox Code Playgroud)
因为在你的问题中,你曾要求Map使用数组引用而不是数组,这里有一个适用于数组引用的版本,它map与纯内置函数一样接近内置函数.
use 5.010;
use warnings;
use strict;
sub Map (&\@) {
my ($code, $array) = splice @_;
my @return;
push @return, &$code for @$array;
@return
}
my @sample = qw(1 2 3 4 5);
say join ', ' => Map { $_ * $_ } @sample; # 1, 4, 9, 16, 25
say join ', ' => map { $_ * $_ } @sample; # 1, 4, 9, 16, 25
Run Code Online (Sandbox Code Playgroud)
在原型中Map,(&\@)原型告诉perl Map将使用与通常的子例程不同的规则来解析裸字.的&指示的第一个参数要么是裸块Map {...} NEXT或这将是一个文字代码引用Map \&somesub, NEXT.请注意后一版本中的参数之间的逗号.所述\@原型表示下一个参数将开始与@和作为数组引用将被传递英寸
最后,该splice @_行清空@_而不是仅仅复制值.这样&$code行就会看到空的@_而不是args Map.原因&$code是它是调用子例程的最快方法,并且与map不使用C时可以使用的多字符调用样式一样接近.这种调用样式非常适合这种用法,因为块的参数是$_,它不需要任何堆栈操作.
在上面的代码中,我作弊一点,让我们for做本地化的工作$_.这对性能有好处,但要看它是如何工作的,这里是重写的那一行:
for my $i (0 .. $#$array) { # for each index
local *_ = \$$array[$i]; # install alias into $_
push @return, &$code;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1207 次 |
| 最近记录: |