2008-08-15 14 views
5

cuando estoy ejecutando la siguiente instrucción:¿Por qué mi mapa de Perl no devuelve nada?

@filtered = map {s/ //g} @outdata; 

se está volviendo una lista vacía en lugar de la lista filtrada que yo esperaba. Lo que intento hacer es eliminar cada aparición de   de una matriz de cadenas (que es un archivo XML).

Obviamente, no entiendo nada. ¿Puede alguien decirme que la forma correcta de hacer esto podría ser, y por qué esto no funciona para mí tal como está?

+0

esto está relacionado con http://stackoverflow.com/questions/1458454/why-is-the-list-my-perl-map-returns-just-1s/1461242#1461242, y tiene la la misma respuesta. –

Respuesta

10

Prueba esto:

@filtered = map {s/ //g; $_} @outdata; 

El problema es que el operador s en Perl modifica $ _ pero en realidad devuelve el número de cambios que hizo. Entonces, el $ _ adicional al final hace que perl devuelva la cadena modificada para cada elemento de @outdata.

+5

Este código destruye los valores en @outdata. –

+6

No me siento lo suficientemente malo como para rechazar votos, pero esta es una mala idea. http://stackoverflow.com/questions/12103/why-doesnt-my-perl-map-return-anything/21792#21792 es una respuesta mucho mejor. –

+0

Con [la sustitución no destructiva de Perl 5.14] (http://www.effectiveperlprogramming.com/2010/09/use-the-r-substitution-flag-to-work-on-a-copy/), usted puede hacer esto como '@filtered = map {s/  // gr} @ outdata' sin afectar' @ outdata'. –

3

Como contrapunto a la respuesta de Greg, que podrían hacer mal uso grep:

@filtered = grep {s/ //g; 1} @outdata; 

No haga esto.

15

Tenga en cuenta que el mapa también modificará su matriz fuente. Por lo que podría hacer, ya sea:

map {s/ //g} @outdata; 

y omitir la variable @filtered por completo, o si necesita conservar los originales,

@filtered = @outdata; 
map {s/ //g} @filtered; 

Aunque, en ese caso, podría ser más fácil de leer para usar foreach:

s/ //g foreach @filtered; 
+0

'map' en contexto vacío generalmente se considera de forma incorrecta y no dice nada sobre' para @filtered {...} '. –

6

Para dar seguimiento a punto de Tithonium, esto también hará el truco:

@filtered = map {local $_=$_; s/ //g; $_} @outdata; 

El "local" garantiza que está trabajando en una copia, no en el original.

9

La respuesta de Greg tiene el problema de que modificará la matriz original cuando se pasen los $ _ alias. Es necesario:

@filtered = map { (my $new = $_) =~ s/ //g; $new} @outdata; 
4
use Algorithm::Loops "Filter"; 
@filtered = Filter { s/ //g } @outdata; 
Cuestiones relacionadas