2008-08-15 16 views
5

Kiedy używam następujące oświadczenie:Dlaczego moja mapa Perla nie zwraca niczego?

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

to wraca pustą listę zamiast przefiltrowanej listy spodziewałem. Co próbuję zrobić, to usunąć wszystkie wystąpienia   z tablicy ciąg (który jest plikiem XML).

Oczywiście, nie rozumiem czegoś. Czy ktoś może mi powiedzieć, jak to zrobić, i dlaczego to nie działa tak jak ja?

+0

Wiąże się to http://stackoverflow.com/questions/1458454/why-is-the-list-my-perl-map-returns-just-1s/1461242#1461242, a to ma ta sama odpowiedź. –

Odpowiedz

10

Spróbuj tego:

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

Problemem jest operator s Perl modyfikuje $ _ ale faktycznie zwraca liczbę zmian to wykonane. Tak więc dodatkowy $ _ na końcu powoduje, że perl zwraca zmieniony ciąg znaków dla każdego elementu @ outdata.

+5

Ten kod usuwa wartości z @ outdata. –

+6

Nie jestem wystarczająco przygnębiony, by zgodzić się, ale to zły pomysł. http://stackoverflow.com/questions/12103/why-doesnt-my-perl-map-return-nething/21792#21792 jest znacznie lepszą odpowiedzią. –

+0

Z [Perl 5.14 nieniszczącej substytucji] (http://www.effectiveperlprogramming.com/2010/09/use-t-substitution-flag-to-work-on-a-copy/), ty można to zrobić tak, jak '@filtered = map {s/  // gr} @ outdata' bez wpływu na' @ outdata'. –

3

Jako kontrapunkt do odpowiedzi Grega, można nadużywać grep:

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

nie rób tego.

15

Należy zauważyć, że mapa ma również modyfikować tablicę źródłową. Więc można albo zrobić:

map {s/ //g} @outdata; 

i pominąć zmienną @filtered całkowicie, lub jeśli chcesz zachować oryginały,

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

Chociaż w tym przypadku może być bardziej czytelny w obsłudze foreach:

s/ //g foreach @filtered; 
+0

'mapa' w pustym kontekście jest ogólnie uważana za słabą formę i nie mówi nic ponad' dla @filtered {...} '. –

6

Aby śledzić na punkcie Tithonium, ten będzie również rade:

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

"Lokalny" zapewnia, że ​​pracujesz na kopii, a nie na oryginale.

9

Odpowiedź Grega ma problem polegający na tym, że zmodyfikuje oryginalną tablicę jako alokowaną wartość _ _. Potrzebne są:

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