如何使用map将函数应用于列表?

pla*_*etp 9 perl map

我想将一个函数应用于列表的每个项目并存储类似于map(function, list)python的结果.

试图传递一个函数来映射,但得到了这个错误:

perl -le 'my $s = sub {}; @r = map $s 0..9'
panic: ck_grep at -e line 1.
Run Code Online (Sandbox Code Playgroud)

这样做的正确方法是什么?

FMc*_*FMc 9

如果标量变量包含代码引用 - 例如:

my $double = sub { 2 * shift };
Run Code Online (Sandbox Code Playgroud)

您可以像在Python中那样调用代码,如下所示:

$double->(50);  # Returns 100.
Run Code Online (Sandbox Code Playgroud)

将其应用于map示例:

my @doubles = map $double->($_), 1..10;
Run Code Online (Sandbox Code Playgroud)

或者这样:

my @doubles = map { $double->($_) } 1..10;
Run Code Online (Sandbox Code Playgroud)

第二个变体更健壮,因为{}大括号定义的块可以包含任意数量的Perl语句:

my @doubles = map {
    my $result = 2 * $_;

    # Other computations, if needed.

    $result;  # The return of each call to the map block.
} 1..10;
Run Code Online (Sandbox Code Playgroud)


OMG*_*uts 5

尝试:map { $s->($_) } (0..9)而不是map $s 0..9

解释:在您的示例中,$s是对子例程的引用,因此您必须取消引用它以允许子进程调用.这可以通过以下几种方式实现:$s->()或者&$s()(可能还有其他一些我忘记的方式)


tch*_*ist 5

  my $squared = sub {
        my $arg = shift();
        return $arg ** 2;
  };
Run Code Online (Sandbox Code Playgroud)

那么要么

   my @list = map { &$squared($_)  } 0 .. 12;
Run Code Online (Sandbox Code Playgroud)

或者

   my @list = map { $squared->($_) } 0 .. 12;
Run Code Online (Sandbox Code Playgroud)

或者可能

my $squared;
BEGIN {
    *Squared = $squared = sub(_) {
        my $arg = shift();
        return $arg ** 2;
    };
}
my @list = map { Squared } 0 .. 12;
Run Code Online (Sandbox Code Playgroud)