2010-11-18 8 views
7

Quiero aplicar una función a cada elemento de una lista y almacenar resultados similares a map(function, list) en python.¿Cómo puedo aplicar una función a una lista usando el mapa?

trató de pasar de una función a mapear, pero tiene este error:

perl -le 'my $s = sub {}; @r = map $s 0..9' 
panic: ck_grep at -e line 1. 

¿Cuál es la forma correcta de hacer esto?

Respuesta

7

Si una variable escalar contiene una referencia de código - por ejemplo:

my $double = sub { 2 * shift }; 

Puede invocar el código mucho la forma en que lo haría en Python, así:

$double->(50); # Returns 100. 

La aplicación de eso a un map ejemplo:

my @doubles = map $double->($_), 1..10; 

O esta manera:

my @doubles = map { $double->($_) } 1..10; 

La segunda variante es más robusto debido a que el bloque definido por los {} tirantes puede contener cualquier número de estados de Perl:

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

    # Other computations, if needed. 

    $result; # The return of each call to the map block. 
} 1..10; 
+1

agradable respuesta, también observamos que en el bloque de mapa, a diferencia de la mayoría de los otros bloques, puede instalar _No_ pragmas léxicas o realizar otras acciones en tiempo de compilación ('uso ... '/' no ... '). –

+0

Puede usar * use * y * no * en * map BLOCK LIST * formas de * map *, no en * map EXPR LIST * formularios, es solo que si los usa puede necesitar desambiguar el bloque de una expresión con un líder; Alternativamente, puede usar * do BLOCK * como expresión, y puede contener * no * y * use *. usar estricto; mi @ a = 1..10; my @b = map {; no estrictos 'vars'; $ x = $ _ + 1; $ x} @a; my @c = map {do {no strict 'vars'; $ x = $ _ + 1; $ x}} @a; – MkV

+0

También vale la pena señalar que el * $ _ * en el ciclo es un alias para los elementos del conjunto, por lo que modificarlo modifica el conjunto de origen, que no se recomienda para el código claro. – MkV

5

intento: map { $s->($_) } (0..9) en lugar de map $s 0..9

explicación: en ti ejemplo, $s es una referencia a una subrutina, por lo que debe eliminar la referencia a permitir una llamada subroutin. Esto se puede lograr de varias maneras: $s->() o &$s() (y probablemente algunas otras maneras que me estoy olvidando)

4
my $squared = sub { 
     my $arg = shift(); 
     return $arg ** 2; 
    }; 

entonces o bien

my @list = map { &$squared($_) } 0 .. 12; 

o

my @list = map { $squared->($_) } 0 .. 12; 

o tal vez

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

No es demasiado diferente de Python.

@results = map { function($_) } @list; 
@results = map function($_), @list; 

o con "lambda",

@results = map { $function->($_) } @list; 
@results = map $function->($_), @list; 
Cuestiones relacionadas