2010-11-18 15 views
7

Je souhaite appliquer une fonction à chaque élément d'une liste et stocker des résultats similaires à map(function, list) en python.Comment puis-je appliquer une fonction à une liste en utilisant map?

a essayé de passer une fonction à la carte, mais nous avons eu cette erreur:

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

Quelle est la bonne façon de le faire?

Répondre

7

Si une variable scalaire contient une référence de code - par exemple:

my $double = sub { 2 * shift }; 

Vous pouvez appeler le code très bien comme vous le feriez en Python, comme ceci:

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

application qui à un map exemple:

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

Ou cette façon:

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

La deuxième variante est plus robuste, car le bloc défini par les {} accolades peut contenir un certain nombre de déclarations Perl:

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

    # Other computations, if needed. 

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

Belle réponse, notez que dans le bloc de carte, contrairement à la plupart des autres blocs, vous pouvez _not_ installer pragma lexicales ou faire d'autres actions de temps de compilation ('utilisation ... '/' non ... '). –

+0

Vous pouvez utiliser * use * et * no * dans * map BLOCK LIST * formes de * map *, pas dans * map EXPR LIST * forms, c'est juste que si vous les utilisez vous devrez peut-être désambiguïser le bloc d'une expression avec un leader. Alternativement, vous pouvez utiliser un * do BLOCK * comme expression, et qui peut contenir * no * et * use *. utiliser strict; mon @a = 1..10; mon @b = carte {; pas de «vars» stricts; $ x = $ _ + 1; $ x} @a; my @c = map {do {pas de 'vars' strict; $ x = $ _ + 1; $ x}} @a; – MkV

+0

Il convient également de noter que * $ _ * dans la boucle est un alias pour les éléments du tableau, donc la modifier modifie le tableau source, ce qui n'est pas recommandé pour effacer le code. – MkV

5

essayer: map { $s->($_) } (0..9) au lieu de map $s 0..9

explication: en vous par exemple, $s est une référence à un sous-programme, vous devez donc déréférencer pour permettre les appels subroutin. Ceci peut être réalisé de plusieurs façons: $s->() ou &$s() (et probablement d'autres moyens que je oublie)

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

alors soit

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

ou

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

ou peut-être

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

Il est pas trop différent de Python.

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

ou « lambdas »,

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