2008-08-15 8 views
5

Когда я бегу следующее заявление:Почему моя карта Perl ничего не возвращает?

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

она возвращается пустой список вместо отфильтрованного списка, который я ожидал. То, что я пытаюсь сделать, - удалить каждое возникновение   из массива строки (который является XML-файлом).

Очевидно, что я ничего не понимаю. Может ли кто-нибудь сказать мне, как правильно это сделать, и почему это не работает для меня, как есть?

+0

Это связано с http://stackoverflow.com/questions/1458454/why-is-the-list-my-perl-map-returns-just-1s/1461242#1461242, и она имеет такой же ответ. – 2015-08-17 18:17:31

ответ

10

Попробуйте это:

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

Проблема заключается в s операторе в Perl изменяет $ _, но на самом деле возвращает количество изменений, которые она сделала. Таким образом, дополнительные $ _ в конце заставляют perl возвращать модифицированную строку для каждого элемента @outdata.

+5

Этот код уничтожает значения в @outdata. – 2009-11-23 21:15:57

+6

Я не чувствую себя достаточно сильным, чтобы понизить, но это плохая идея. http://stackoverflow.com/questions/12103/why-doesnt-my-perl-map-return-anything/21792#21792 - гораздо лучший ответ. – 2010-01-02 08:54:29

3

В противовес ответ Грега, вы могли бы злоупотребить Grep:

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

Не делайте этого.

15

Обратите внимание, что карта также изменит ваш исходный массив. Таким образом, вы можете либо сделать:

map {s/ //g} @outdata; 

и пропустить @filtered переменную вообще, или если вам нужно сохранить оригиналы,

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

Хотя, в этом случае, это может быть более удобным для чтения, чтобы использовать Еогеасп:

s/ //g foreach @filtered; 
6

Чтобы следить за точкой Tithonium, это будет также сделать трюк:

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

«Локальный» гарантирует, что вы работаете над копией, а не оригиналом.

9

У Greg есть проблема, что он изменит исходный массив, поскольку $ _ передается с псевдонимом. Вам нужно:

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